Question:
C++ Bug with operator= Function?
1970-01-01 00:00:00 UTC
C++ Bug with operator= Function?
Five answers:
oops
2012-09-05 21:21:49 UTC
It's undefined behavior to declare that a function returns a value, but then not actually return a value (unless you throw an exception, of course).



So, "where" the garbage comes from, is irrelevant, and it's extremely unlikely that a debugger will be able to help you here, because you are right, no object is being constructed. So, what happens here:



    fooOne = (fooTwo = fooThree);



is (probably) that the compiler looks for where the return object should have been constructed, treats that location as though an object exists there, and assigns that object to fooOne. However, since no object was ever constructed there, you get garbage. I say "probably", because, like I said, it's undefined behavior, so any thing could happen, as far as the standard is concerned.
husoski
2012-09-05 21:36:06 UTC
The bug I see is that you left out a return statement required at the end of operator=(). That's an error that the compiler should have flagged. (You mention gdb, so I assume the compiler is g++. That's strange. I haven't ever seen GNU C/C++ miss an outright error like this.) You should have:



CFoo& CFoo::operator=(const CFoo& copy)

{

strcpy(m_strOne, copy.m_strOne);

strcpy(m_strTwo, copy.m_strTwo);

return *this;

}



I can't see the class, but the string handling looks like it needs work. strcpy() is one of those dangerous functions to avoid in C and C++. If those string m_strOne and m_strTwo are fixed-size arrays, all the same size, and the constructor and methods guarantee that every string is 0-terminated, then strcpy() is safe. If the strings are allocated to actual size, with new[] or malloc(), then you need to make sure the receiving string is big enough.



Safe handling of variable-length strings is part of what the string class in gives you. Consider using those if the assignment isn't about learning to use functions.



Edit: Okay, I found it in the standard...and it is undefined, not an error. But, it's still an error in my view.



C++2003: 6.6.3(2) ... Flowing off the end of a function is equivalent to a return with no value; this results in undefined behavior in a value-returning function.



...with one screwy exception for main:



C++2003: 3.6.1(5) ... If control reaches the end of main without encountering a return statement, the effect is that of executing return 0;



I checked the MinGW port of g++ and it spits out a warning even without -Wall or -pedantic. If you check your messages, you should see a warning. It's a good idea to take a look at every warning every time. I'm in the habit of using -Wall and -pedantic, and then making every warning go away before a coding round is done. I'm more familiar with the error/warning structure of VC++, so there I usually turn on "treat warnings as errors" too, so I don't even bother debugging code that has sketchy syntax.
?
2016-10-12 07:13:03 UTC
First, use pastebin to stick formatted code. 2nd, stacks are frequently carried out as appropriate-lists, no longer contiguous arrays, on the grounds which you do no longer desire Order(a million) get admission to to any aspects different than the pinnacle. A dynamic array is carried out in the STL vector type. in case you like a reference, you are able to view the code for the vector type, which will develop the size of the indoors array by using a million.5x (final I checked) because it fills. third, this is totally almost my bedtime and my eyes are heavy, so i'm going to come again and seem at your code later. additionally, the different answerer "James Bond" solutions a great style of programming questions, yet gets approximately 80% of them incorrect and makes use of damaging practices in the different 20%, so be careful of any suggestion you're taking from him.
?
2012-09-05 21:22:55 UTC
See the following code. It did work.

#include

#include

#include

using namespace std;

class CFoo

{

char str[20];

public:

CFoo(){}

CFoo(char x[])

{

strcpy(str,x);

}

void out()

{

cout<
}

CFoo& operator=(const CFoo& copy)

{

strcpy(str, copy.str);



}

};

int main()

{

CFoo A("Ram");

CFoo B,C;

C=B=A;

A.out();

B.out();

C.out();

system("PAUSE");

return 0;

}
Ratchetr
2012-09-05 22:10:33 UTC
I have to agree 110% with Ooops on this one.



The lack of the return statement is undefined behavior. I was a bit surprised by this. My first thought was that this code should not compile. And it won't compile.... using Microsoft C++. It generates an error due to the lack of a return. But, that error isn't required by the standard.



Found this bit (see first link):

$6.6.3/2 - "Flowing off the end of a function is equivalent to a return with no value; this results in undefined behavior in a value-returning function."



So...Exactly what Oops already said. Once you enter into the world of undefined behavior, it doesn't matter why it does or doesn't work.



I was curious about the code that James B. posted. It does in fact compile and run on my machine using a rather old version of g++ on Cygwin. And it produces the "right" results. But that is just dumb luck.



Posted the same code to Ideone (see second link). After adding a #include to get it to compile, it seg faults when run.



Welcome to the world of undefined behavior ;-). It works on my machine, and it works on JB's machine. But it barfs on your students machine and on ideone. And it won't even compile on my machine with Visual Studio.



One thing mentioned in the SO link is: Use the -Wall option when you compile. This is what I get with the James Bond code:

$ g++ -Wall test.cpp

test.cpp: In member function `CFoo& CFoo::operator=(const CFoo&)':

test.cpp:23: warning: no return statement in function returning non-void

test.cpp:23: warning: control reaches end of non-void function



That makes it obvious that a) something is wrong, and b) exactly what and where the problem is.



Since you are a teacher, I would *strongly* suggest that you encourage (require?) your students to compile using the -Wall option. And *strongly* suggest (require?) that the code compiles without any warnings.



That will make your students life harder. And it will probably make your life harder, because you will get pestered with questions about warnings that probably don't matter. But ignoring warnings in C++ can lead to nasty surprises....as you and your student have just learned. It isn't at all uncommon in some organizations to *require* that code compiles without warnings. If I check in code that generates warnings, then I hear about it. I just broke the build, because that code *will not* be released. The fact that the code 'seems' to work doesn't matter.



I don't complain about that, because it's a good policy. I just fix the warnings and remind myself not to be so careless next time.



ETA: I agree 110% with husoski too ;-)


This content was originally posted on Y! Answers, a Q&A website that shut down in 2021.
Loading...