Thread: about return value

  1. #1
    Registered User
    Join Date
    Apr 2011
    Posts
    10

    about return value

    For C++ programmers, if a function needs to return a value to indicate MULTIPLE status, such like success and different situations of failure(more than one, so can't return bool), what value should be returned to indicate success in "c++ standard"? Is there such standard?

  2. #2
    Registered User
    Join Date
    Jun 2005
    Posts
    6,815
    There is no universal solution, but there are many options. Look up the different ways that a function can return data to the caller. You'll learn better if you hunt for the information yourself (it is not that hard to find in basic introductory texts) rather than being spoonfed.
    Right 98% of the time, and don't care about the other 3%.

    If I seem grumpy or unhelpful in reply to you, or tell you you need to demonstrate more effort before you can expect help, it is likely you deserve it. Suck it up, Buttercup, and read this, this, and this before posting again.

  3. #3
    template<typename T> threahdead's Avatar
    Join Date
    Sep 2002
    Posts
    214
    A hint, take a look at structs.

  4. #4
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    "Bitflags" are pretty popular, you have perhaps had to use them even if you haven't implemented them yourself:

    Code:
    #include <iostream>
    #include <string>
    
    #define OK	0
    #define TOO_SHORT 1
    #define INVALID_CHAR 2
    #define NO_CAP 4
    
    using namespace std;
    
    int validate_password (const string &pw) {
    	int rv = OK, i, cap = 0, len = pw.length();
    	if (len < 8) rv |= TOO_SHORT;
    	for (i = 0; i < len; i++) {
    		if (pw[i] < '0' || (pw[i] > '9' && pw[i] < 'A')
    		  || (pw[i] > 'Z' && pw[i] < 'a') || pw[i] > 'z') {
    			rv |= INVALID_CHAR;
    			continue;
    		}
    		if (pw[i] >= 'A' && pw[i] <= 'Z') cap++;
    	}
    	if (!cap) rv |= NO_CAP;
    	return rv;
    }
    
    int main(int argc, const char *argv[]) {
    	string eg;
    	cout << "Enter password: ";
    	cin >> eg;
    
    	int err = validate_password(eg);
    	cout << "Validating \"" << eg << "\"...\n";
    	if (err) {
    		if (err & TOO_SHORT) cout << "Password must be 8+ characters.\n";
    		if (err & INVALID_CHAR) cout << "Password must be only alphanumeric characters.\n";
    		if (err & NO_CAP) cout << "Password must contain a capital letter\n";
    	} else cout << "All good!\n";
    
    	return 0;
    }
    Notice that the values of the flags are exponential -- 1, 2, 4 -- and not sequential -- 1, 2, 3. If you don't know why that is, you should, so ask. Anyway, a single int using bitflags can be used to return upto 32 (1 per bit) different possibilities alone, and in combination:

    Code:
    [root~/C++] ./a.out
    Enter password: asdf1234
    Validating "asdf1234"...
    Password must contain a capital letter
    [root~/C++] ./a.out
    Enter password: g56$
    Validating "g56$"...
    Password must be 8+ characters.
    Password must be only alphanumeric characters.
    Password must contain a capital letter
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  5. #5
    template<typename T> threahdead's Avatar
    Join Date
    Sep 2002
    Posts
    214
    Quote Originally Posted by MK27 View Post
    "Bitflags" are pretty popular, you have perhaps had to use them even if you haven't implemented them yourself:
    wrong thread?

  6. #6
    spurious conceit MK27's Avatar
    Join Date
    Jul 2008
    Location
    segmentation fault
    Posts
    8,300
    Quote Originally Posted by threahdead View Post
    wrong thread?
    In what sense? The OP's question:

    Quote Originally Posted by talentspsp View Post
    if a function needs to return a value to indicate MULTIPLE status, such like success and different situations of failure(more than one, so can't return bool), what value should be returned
    Using bitflags to do that is certainly very common.

    Maybe this was left implicit, but a value of OK (zero) cannot contain any flags, because 0 == no bits set. So returning 0 indicates success, anything else indicates an error, and then you AND test the int to see which error states are set:

    Code:
    	if (err) {
    		if (err & TOO_SHORT) cout << "Password must be 8+ characters.\n";
    		if (err & INVALID_CHAR) cout << "Password must be only alphanumeric characters.\n";
    		if (err & NO_CAP) cout << "Password must contain a capital letter\n";
    	} else cout << "All good!\n";
    So that single int can contain multiple states -- it can be TOO_SHORT and also INVALID_CHAR, or it could just be one or the other. In the example, these all pertain to one thing, but they could pertain to completely different things. The point being, it's all contained in a single return value.

    Of course, you don't have to use the zero to indicate success. If you have a non-zero flag(s) for success, then you can return success and also indicate the kind of success:

    Code:
    #define SUCCESS_A 8
    #define SUCCESS_B 16
    You can make "flags" an int field in a struct too, also very common. Again, if anyone does not understand the nature of logical AND(&, different from &&, the "and" operator), logical OR (|, different from ||, the "or" operator) and bit ops generally, just ask or google "bitflags", "bitmask" or "bit operations". They are certainly the most efficient way to do something like this and also a programming fundamental everyone should understand.

    Bitflags/bitmasks (same thing) are also used to set multiple possibilities. For example, the second parameter to ofstream is a bitmask:

    Code:
    ofstream ("somefile", ios_base::out | ios_base::binary | ios_base::trunc);
    Opens a binary file for writing, and truncates it's length to zero. The parameter is type ios_base :: openmode which is an unsigned int.
    Last edited by MK27; 04-30-2011 at 08:22 AM.
    C programming resources:
    GNU C Function and Macro Index -- glibc reference manual
    The C Book -- nice online learner guide
    Current ISO draft standard
    CCAN -- new CPAN like open source library repository
    3 (different) GNU debugger tutorials: #1 -- #2 -- #3
    cpwiki -- our wiki on sourceforge

  7. #7
    template<typename T> threahdead's Avatar
    Join Date
    Sep 2002
    Posts
    214
    Quote Originally Posted by MK27 View Post
    Using bitflags to do that is certainly very common.
    Absolutely.
    But using structs, or something similar, is easier to grasp though. There is no need to understand how a number is represented in binary for that.

  8. #8
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Code:
    #define OK	0
    #define TOO_SHORT 1
    #define INVALID_CHAR 2
    #define NO_CAP 4
    Those defines really should be constants:
    Code:
    const int OK = 0;
    const int TOO_SHORT = 1;
    const int INVALID_CHAR = 2;
    const int NO_CAP = 4;
    Quote Originally Posted by Adak View Post
    io.h certainly IS included in some modern compilers. It is no longer part of the standard for C, but it is nevertheless, included in the very latest Pelles C versions.
    Quote Originally Posted by Salem View Post
    You mean it's included as a crutch to help ancient programmers limp along without them having to relearn too much.

    Outside of your DOS world, your header file is meaningless.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 1
    Last Post: 07-04-2007, 12:20 AM
  2. Replies: 12
    Last Post: 04-07-2007, 11:11 AM
  3. Replies: 6
    Last Post: 04-09-2006, 04:32 PM
  4. Replies: 4
    Last Post: 07-15-2005, 04:10 PM
  5. Return Return Error
    By javacvb in forum C++ Programming
    Replies: 8
    Last Post: 12-16-2003, 04:17 PM