Anyone know where this value comes from?

Started by
8 comments, last by Spoonbender 18 years, 10 months ago
Anyone know why the bool gets the value 196 when I leave out a return statement in the bool operator== overload? Not sure where that is coming from, can anyone explain?
#include <iostream>
using namespace std;

class String{
      public:           
             String(string arg): _sVal(arg){}            
             String(char *arg): _sVal(string(arg)){}
             friend ostream& operator<<(ostream &s,const String &ss);
             bool operator==(const String &str){
                  (strcmp((this->_sVal.c_str()),(str._sVal.c_str())) ? false : true);
             }
             
      private:
              string _sVal;
};

ostream& operator<<(ostream &stream,const String &ss){         
         return (stream << ss._sVal);       
}

int main(){
    String s("HIIIE");
    cout << s << endl;   
    String s1("HIIIE");;
    bool b = (s1==s);
    cout << b << endl;
} 
Advertisement
Without a return statement, no value is actually returned, so whatever is actually left in the bool variable is just random junk left over from allocation (since you never bothered to initialize it before trying to assign it).

EDIT: Also, just as an aside, you don't really need that strcmp call. std::string already implements operator==(). Converting to C-style const strings then comparing using C-style comparison functions, is considered bad form by a lot of people here, and me get you slapped upside the head with a dead trout.
i think something is being returned though, when i comment out the definition of the overloaded operator it gets a value of 64

i initialized it to 0 and it still gets that value in it anyway, somehow the function is returning a value even though there is no return statement.

thanks for the advice, my book says to use string too but it wanted me to overload the operators for an exercise, such as using == with a C-style string and a C++ string
Quote:Original post by Gink
i think something is being returned though, when i comment out the definition of the overloaded operator it gets a value of 64

i initialized it to 0 and it still gets that value in it anyway, somehow the function is returning a value even though there is no return statement.


This is the result of UNDEFINED BEHAVIOR. When a function hits the end without returning when it's return type is not void, the result is UNDEFINED, and the result is often either GARBAGE VALUES, or with some calling mechanisms, STACK CORRUPTION which will most likely CRASH your program.

With some compilers, the program will immediately crash, due to invalid instructions or the like at the tail of the assembly.

Your fix is very simple... change this line:

(strcmp((this->_sVal.c_str()),(str._sVal.c_str())) ? false : true);

to:

return (strcmp((this->_sVal.c_str()),(str._sVal.c_str())) ? false : true);

And your program will re-enter the land of DEFINED behavior.
lol mauling, i know the return statement was missing. Are there any articles on what undefined behavior generally is, or is it completely random?
Quote:Original post by Gink
lol mauling, i know the return statement was missing. Are there any articles on what undefined behavior generally is, or is it completely random?


As far as the standard is concerned, it can be completely random. Or it can do what you expect. Or it can do what I expect (which isn't necessarily what you expect). Or it can make demons fly out of your nose. Basically, the standard doesn't define (i.e. it is undefined) what happens, so the implementation can do whatever it pleases.

Here, "implementation" is referring to your version of your compiler, your version of your OS, your version of your hardware connected the way it is in your computer, etc. Thus, even changing versions of one of those links can change the behavior (different optimization strategies, etc.). How serious of a problem this is depends on the nature of the program, your tolerances, and the implementations you hope to run on.
Undefined behavior is a nasty beastie. Unfortunately, the C++ language allows you to do half a bazillion things that are undefined. And I do mean a full half a bazillion. To put it in perspective, some google searches and their numbers:

Google Search: Undefined Behavior (~1,010,000 hits, 100%)
Google Search: Undefined Behavior C (~730,000 hits, 72.3%)
Google Search: Undefined Behavior C++ (~170,000 hits, 16.8%)
Google Search: Undefined Behavior C C++ (~158,000 hits, 15.6%)
Google Search: Undefined Behavior C/C++ (~46,200 hits, 4.57%)

(Remember, C++ inherits a lot of C's behavior)

I'm not aware of any articles specifically about undefined behavior, but needless to say such an article would probably be pretty huge. Good compilers should issue warnings for many of them as long as you turn them on... accessing uninitialized variables, possibly reaching the end of a function that needs to return something without returning, passing objects to an elipse function (read: passing std::string to printf)... the list goes on and on.

Undefined behavior also has the unfortunate property of possibly working just as you expect, or possibly launching nuclear missiles at a cow ranch in Alaska, or possibly crashing 5 hours after the behavior is triggered (which needless to say is a pain in the ass to debug). To make matters even worse, the behavior can change - it's like the computer that refuses to crash in front of a tech, like my friend's computer which kept rebooting... whenever I wasn't there.

Purely random behavior would probably be an improvement on undefined behavior. At least with purely random, if you stare at the problem long enough, statistically, the problem should reveal itself. Not so with undefined behavior.
Basically, a function *has* to return something - basically, there's a chunk of memory on the stack which is conceptually tagged "here is the return value", and in the compiled code, that value will be moved somewhere useful (i.e. that the calling function can see) when the function returns.

If the function reaches the end, it "returns". The value returned is what's in that chunk of memory. If nothing was explicitly put there (by means of a return statement in the C++ code - more accurately, by means of the machine code generated from that C++ code), then the value returned is still what's in that chunk of memory - i.e. whatever happened to be there from before. Figuring out exactly what that might be is potentially very complicated. In general, it cannot be determined just by looking at the code, because any given code can be compiled in a gazillion different ways (with the same net effect; just variances in how it performs). And in general, it will not be anything meaningful or at all useful.

So WRT undefined behaviour, Just Don't Freakin Do It. It is worthwhile to develop coding habits that insure you against accidentally doing this kind of thing. However, I'm not a psychologist and I certainly am not YOUR psychologist, so I can't tell you how best to do that. (Although there are some reasonably good ideas floating around, you may find that the best thing is to just be Disciplined(TM).)
This is basically the same as what you are doing:
void printGarbage(){  int dummy;  cout << dummy;}
You pretty much get what's coming to ya if ya do that.

In your case if you change the code you get a different value because it's just whatever garbage was left in eax when it returned.
"In order to understand recursion, you must first understand recursion."
My website dedicated to sorting algorithms
Quote:Original post by Gink
lol mauling, i know the return statement was missing. Are there any articles on what undefined behavior generally is, or is it completely random?


It's, err, undefined. Of course it isn't random, but it can seem that way. It just means "There are no rules for what should happen now, so you can't rely on whatever result comes out"

Of course the function always "returns" a value. Or rather, there is always a value in the register that's used for return values. Even if the function doesn't have a return statement. But if it doesn't have a return statement, the value of that register is undefined. It's just whatever happened to be in that register at the time, because you don't overwrite it with the proper return value.

This topic is closed to new replies.

Advertisement