Thread: Return statement is NOT exiting the function!!!

  1. #1
    Registered User Vespasian's Avatar
    Join Date
    Aug 2011
    Posts
    181

    Return statement is NOT exiting the function!!!

    EDIT: Title of thread should read "Return statement affected by other return statements"

    Hi all, I have a piece of code that resembles the following:

    Code:
    int locomotives_required (double tons_per_wagon, double train_tons, double gradient)
    {
        double tons_per_axle_variable = tons_per_axle(tons_per_wagon);
        ifstream ifs;
        ifs.open ("C:\\C++ Projects\\Coal Logistics\\LoadTables.txt", std::ofstream::out | std::ofstream::app);
        string lineread;
        getline (ifs, lineread);
        char* wordptr = tokenizer(lineread);
        int number = atoi(wordptr);
        int j;
        int locomotive_counter = 0;
        if (tons_per_axle_variable < number)
            return ERROR_LOW_WAGON_WEIGHT;
        for (int i = 1; *wordptr != 'EOF'; i++) //select the correct table
        {
            wordptr = tokenizer("NULL");
            if (tons_per_axle_variable < atof(wordptr))
                for (j = 1; j <= 18; j++)
                {
                    getline (ifs, lineread);
                    if (gradient == atof(tokenizer(lineread)))
                        for (int k = 0; k <= 6; k++)
                        {
                            locomotive_counter++;
                            if (train_tons <= atof(tokenizer("NULL")))
                                return 3;
                        }
                }
                if (j == 19)
                    return ERROR_HIGH_GRADIENT;
            else
            {
                getline(ifs,lineread);
                while (lineread != "")
                    getline(ifs,lineread);
                getline(ifs,lineread);
                wordptr = tokenizer(lineread);
            }
        }
        if (*wordptr == 'EOF')
            return ERROR_HIGH_WAGON_WEIGHT;
    }
    Neglecting all the distractions, please look at line number 26. I have written this piece of code such that this called function always returns at line 26, which should return the number 3. I ran a debugger and checked step by step to make sure the function returns at line 26 and it does.

    Note that in theory, the return keywords at lines 30 and 41 should have no bearing on the outcome of returning the value "3" at line 26.

    Yet when I run this program and print the outcome I always get a 6-8 digit random number every time like: 767172 and 393620 etc...

    To solve this problem I COMMENT OUT lines 30 and 41 and rather make an empty statement like " ;" and finally the function returns the value 3 as it should.

    Can anybody explain this???
    Last edited by Vespasian; 01-16-2014 at 11:58 AM.

  2. #2
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Just in case this is the/a reason for the problem, are you aware that this:
    Code:
            if (tons_per_axle_variable < atof(wordptr))
                for (j = 1; j <= 18; j++)
                {
                    getline (ifs, lineread);
                    if (gradient == atof(tokenizer(lineread)))
                        for (int k = 0; k <= 6; k++)
                        {
                            locomotive_counter++;
                            if (train_tons <= atof(tokenizer("NULL")))
                                return 3;
                        }
                }
                if (j == 19)
                    return ERROR_HIGH_GRADIENT;
            else
            {
                getline(ifs,lineread);
                while (lineread != "")
                    getline(ifs,lineread);
                getline(ifs,lineread);
                wordptr = tokenizer(lineread);
            }
    should be correctly indented as:
    Code:
            if (tons_per_axle_variable < atof(wordptr))
                for (j = 1; j <= 18; j++)
                {
                    getline (ifs, lineread);
                    if (gradient == atof(tokenizer(lineread)))
                        for (int k = 0; k <= 6; k++)
                        {
                            locomotive_counter++;
                            if (train_tons <= atof(tokenizer("NULL")))
                                return 3;
                        }
                }
            if (j == 19)
                return ERROR_HIGH_GRADIENT;
            else
            {
                getline(ifs,lineread);
                while (lineread != "")
                    getline(ifs,lineread);
                getline(ifs,lineread);
                wordptr = tokenizer(lineread);
            }
    ?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #3
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Are you actually storing the output somewhere? Or perhaps some other piece of code is overwriting memory it doesn't own.

  4. #4
    Registered User Vespasian's Avatar
    Join Date
    Aug 2011
    Posts
    181
    Quote Originally Posted by laserlight View Post
    Just in case this is the/a reason for the problem, are you aware that this:
    Code:
            if (tons_per_axle_variable < atof(wordptr))
                for (j = 1; j <= 18; j++)
                {
                    getline (ifs, lineread);
                    if (gradient == atof(tokenizer(lineread)))
                        for (int k = 0; k <= 6; k++)
                        {
                            locomotive_counter++;
                            if (train_tons <= atof(tokenizer("NULL")))
                                return 3;
                        }
                }
                if (j == 19)
                    return ERROR_HIGH_GRADIENT;
            else
            {
                getline(ifs,lineread);
                while (lineread != "")
                    getline(ifs,lineread);
                getline(ifs,lineread);
                wordptr = tokenizer(lineread);
            }
    should be correctly indented as:
    Code:
            if (tons_per_axle_variable < atof(wordptr))
                for (j = 1; j <= 18; j++)
                {
                    getline (ifs, lineread);
                    if (gradient == atof(tokenizer(lineread)))
                        for (int k = 0; k <= 6; k++)
                        {
                            locomotive_counter++;
                            if (train_tons <= atof(tokenizer("NULL")))
                                return 3;
                        }
                }
            if (j == 19)
                return ERROR_HIGH_GRADIENT;
            else
            {
                getline(ifs,lineread);
                while (lineread != "")
                    getline(ifs,lineread);
                getline(ifs,lineread);
                wordptr = tokenizer(lineread);
            }
    ?
    You are correct in spotting this but it doesnt affect the code.

    Quote Originally Posted by tabstop
    Are you actually storing the output somewhere? Or perhaps some other piece of code is overwriting memory it doesn't own.
    Nope. The output is a mere integer and returns directly as an integer.

    UPDATE: I only commented out line 41 and it returns the number 3. Line 41 is the culprit but I don't know why? How would one return line (41) mysteriously affect the other (26)?
    Last edited by Vespasian; 01-16-2014 at 12:10 PM.

  5. #5
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Line 41 is what happens if your for-loop on line 14 gets to the end. Therefore, your for-loop on line 14 gets to the end.

  6. #6
    Registered User Vespasian's Avatar
    Join Date
    Aug 2011
    Posts
    181
    Quote Originally Posted by tabstop View Post
    Line 41 is what happens if your for-loop on line 14 gets to the end. Therefore, your for-loop on line 14 gets to the end.
    But it cant get to the end because between line 14 and line 41 is line 26. The conditions leading up to line 26 are all satisfied and the return 3 statement is executed. I even checked with debugging to make sure that the function ends with line 26 and it does. It never reached line 41.

    This is crazy.

  7. #7
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by Vespasian View Post
    But it cant get to the end because between line 14 and line 41 is line 26. The conditions leading up to line 26 are all satisfied and the return 3 statement is executed. I even checked with debugging to make sure that the function ends with line 26 and it does. It never reached line 41.

    This is crazy.
    If that was the case, then changing line 41 would not have made a difference. You can't really have this both ways. I'll reiterate that there can be lots of things wrong in the calling function as well (such as the ever-popular-on-the-forums calling-a-function-but-not-storing-the-return-value), so you need to check there also.

  8. #8
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Vespasian
    You are correct in spotting this but it doesnt affect the code.
    Yes, but it can affect how you reason about your code, i.e., you could have thought that your code should have done something when actually it does something else.

    In fact, it looks like your code is wrong: what if tons_per_axle_variable >= atof(wordptr) on the first iteration of the outer loop? Then you are comparing j with 19, but j was not initialised.

    Quote Originally Posted by Vespasian
    I only commented out line 41 and it returns the number 3.
    You cannot only comment it out because that would result in a compile error. So, what did you replace it with? If you replaced it with an empty return statement or an empty statement, then you have undefined behaviour should control actually reach that point.
    Last edited by laserlight; 01-16-2014 at 09:04 PM.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  9. #9
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    Why do you think the code below is valid?

    Code:
    *wordptr != 'EOF'
    Is 'EOF' valid in C++; because in C its a error or warning!

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  10. #10
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Indeed. Are you compiling with warnings turned on at a high level? Do you pay attention to your compiler warnings?
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  11. #11
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by stahta01 View Post
    Why do you think the code below is valid?

    Code:
    *wordptr != 'EOF'
    Is 'EOF' valid in C++; because in C its a error or warning!

    Tim S.
    It's not valid.
    Either it should be a constant (e.g. wordptr != EOF) or it should be a string (e.g. wordptr != "EOF").
    Of course, those examples are not necessarily valid since I don't know what tokenizer returns or how it works. Plus, wordptr is a C-string, which makes you have to use C-style string functions.
    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.

  12. #12
    Registered User Vespasian's Avatar
    Join Date
    Aug 2011
    Posts
    181
    Okay then, I'm going to look at

    Code:
    *wordptr != 'EOF'
    more carefully and see what I come up with...

    The point I am making is that I find it surprising that although C/C++ is a strictly imperative/procedural language, something like a return statement at the end of the code affects another return statement in the middle of the code even though return statements shouldnt be connected at all. And I cannot see how they are connected to "under the bonnet" of the C/C++ language

  13. #13
    C++まいる!Cをこわせ!
    Join Date
    Oct 2007
    Location
    Inside my computer
    Posts
    24,654
    Quote Originally Posted by Vespasian View Post
    The point I am making is that I find it surprising that although C/C++ is a strictly imperative/procedural language...
    C++ is not strictly an imperative/procedural language. It is a multi-paradigm language (imperative, object oriented, generic among them).

    ...something like a return statement at the end of the code affects another return statement in the middle of the code even though return statements shouldnt be connected at all.
    They don't affect each other.
    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.

  14. #14
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,817
    You should at least have a warning stating something to the effect of "control reaches end of non-void function" for that last bit at the end of the function. Assuming the last "if" test was made correct, there could be the potential that the test failed and the associated return statement would not be executed. You'd then reach the end of the function without an explicit return.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  15. #15
    Registered User Vespasian's Avatar
    Join Date
    Aug 2011
    Posts
    181
    Quote Originally Posted by hk_mp5kpdw View Post
    You should at least have a warning stating something to the effect of "control reaches end of non-void function" for that last bit at the end of the function. Assuming the last "if" test was made correct, there could be the potential that the test failed and the associated return statement would not be executed. You'd then reach the end of the function without an explicit return.
    But this cant be the case because I ran the debugger step by step, and the last step the debugger ran was line 26 indeed proving it exited the function at line 26. It never so much as sniffed line 41

    Quote Originally Posted by Elysia
    It's not valid.
    Either it should be a constant (e.g. wordptr != EOF) or it should be a string (e.g. wordptr != "EOF").
    Of course, those examples are not necessarily valid since I don't know what tokenizer returns or how it works. Plus, wordptr is a C-string, which makes you have to use C-style string functions.
    I changed it to EOF and it if anything its worse off now... Because even commenting out line 41 doesnt work anymore and returns a random number everytime.

    Quote Originally Posted by laserlight
    Indeed. Are you compiling with warnings turned on at a high level? Do you pay attention to your compiler warnings?
    I enabled warnings "demanded by strict ISO C and ISO C++ [-pedantic]" and enabled all warning prompts under compiler flags.

    Yet after I compile I get zero build warnings.


    Im gonna try look at the if statements more closely even though it makes absolutely no sense that one return statement affects the other return statement even though the latter is NEVER called (as proven by the debugger)

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. function exit with out return statement
    By Martin.Ericsson in forum C Programming
    Replies: 3
    Last Post: 11-09-2012, 06:47 AM
  2. Replies: 6
    Last Post: 07-14-2012, 09:26 AM
  3. Pausing before exiting function?
    By Matus in forum C Programming
    Replies: 3
    Last Post: 10-21-2008, 03:00 PM
  4. function - return statement
    By chungt004 in forum C Programming
    Replies: 5
    Last Post: 02-27-2008, 08:33 PM
  5. exiting program and function
    By jumpy in forum C++ Programming
    Replies: 2
    Last Post: 01-17-2003, 02:36 AM