under Linux 2.6.20, KUbuntu Gutsy with gcc 4.1.3 compiling for use on linux #if 0 //first here: //g++ accepts to compile no parameter name is given anytime (not in the class definition neither in the constructor implementation) //the program runs ok though #include <iostream> using namespace std; class Hop { public: Hop(string); void fct(string); }; Hop::Hop(string) {} void Hop::fct(string) {} int main() { Hop a("txt"); return 0; } #endif #if 1 //second: when using an option parameter for constructor //if we use this parameter name again for member initialisation and it's the same as a data member name //this gives no compile pb //+a crash when running #include <iostream> using namespace std; class Hop { public: Hop(string msg="no_msg"); void sayMsg(); string msg; }; Hop::Hop(string):msg(msg) {} void Hop::sayMsg() { cout << "msg is:"<<msg<<"-done" <<endl; } int main() { Hop a("yo"); Hop b(""); a.sayMsg(); b.sayMsg(); return 0; } #endif
Hop::Hop(string):msg(msg) {} Does not reference msg the argument here since there is no such thing.
Hi this is to say that my first example was not a problem so sorry for posting. a conclusion is that c++ tolerates nameless parameter names even in function definition. As to the second example, Andrew Pinski, you state that the parameter msg, which is passed to the string constructor of msg, in the member initialization list. I agree with this, but now given the following class definition: #include <iostream> #include <string> using namespace std; class Something { public: string msg; Something():msg(msg) {} void sayMsg() { cout << "sayMsg() yo here's my message "<< msg << "-done"<<endl; } }; int main() { cout << "crash if nothing after that" << endl; Something a; cout << "msg taken from public is:" << a.msg << "-done"<<endl; a.msg = "yo here's a msg"; a.sayMsg(); cout << "no crash" << endl; getchar(); //pause return 0; } Here are the output of this program: ---when compiled with MS Visual Studio 2005: crash if nothing after that msg taken from public is:-done sayMsg() yo here's my message yo here's a msg-done no crash ----when compiled with g++ (GCC) 3.4.3 (csl-sol210-3_4-branch+sol_rpath) (this is on a solaris. I know this is not 4.1.3 but I'm 99% sure I had the same problem on my linux machine (g++ 4.1.3, i586)). Options used are -Wall and -pedantic and g++ said nothing when compiling: crash if nothing after that Erreur de segmentation //this means Segfault in english The problem is that, at the moment the constructor of Something is called, the constructor of msg (that is to say the constructor of class string) is called and passed msg itself. The problem is that what is passed here does not contain anything yet. If we think lower level, calling the constructor of Something does something in this spirit: 1. allocate memory space for something of the size of a Something object (that is sizeof(string) because class Something only contains one data member which is string msg) 2. read the values of any parameter passed as arguments of the constructor(in our case above, the parameter given does not have a name and is not used anywhere whether in the constructor's body or in its member initialization list, so this step 2. is skipped) 3. do data member initialization. In our case something like this happens: string Something.msg::string(Something.msg) (which calls string's copy constructor I believe). If step 1. if memory allocation were done with a calloc (in C terms...) then unitialized string object msg would be full of zeros, so passing it to string's constructor in step 3. would just pass a zero filled object, and maybe or not, the string's constructor would not complain or crash the whole program. What seems to happen with MS Visual Studio 2005's compiler is this automatic zero-filling on allocation. For g++ it seems that when memory allocation is done (for non-dynamic variables), the allocated spaces are not automatically filled with zeros. So weird things are passed to the string class's constructor in the above case with g++. Hence the segfault. I believe that g++ should raise an error or warning when compiling if we try to pass a data member to its own constructor during member list initialization. What do you think of it ? Sincerely, Jonathan-david Schroder
I did some research this bug has already reported in as 19808 implementation work for it is probably started as I have found this page http://gcc.gnu.org/wiki/Better_Uninitialized_Warnings *** This bug has been marked as a duplicate of 19808 ***