Bug 34307 - when data member name is same as parameter name, possible to omit parameter name in constructor without warning
when data member name is same as parameter name, possible to omit parameter n...
Status: RESOLVED DUPLICATE of bug 19808
Product: gcc
Classification: Unclassified
Component: c++
4.1.3
: P3 normal
: ---
Assigned To: Not yet assigned to anyone
:
Depends on: 19808
Blocks:
  Show dependency treegraph
 
Reported: 2007-12-01 04:06 UTC by Jonathan-david Schroder
Modified: 2007-12-04 21:03 UTC (History)
3 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jonathan-david Schroder 2007-12-01 04:06:15 UTC
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
Comment 1 Andrew Pinski 2007-12-01 11:33:11 UTC

Hop::Hop(string):msg(msg)
{}

Does not reference msg the argument here since there is no such thing.
Comment 2 Jonathan-david Schroder 2007-12-04 20:37:56 UTC
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
Comment 3 Jonathan-david Schroder 2007-12-04 21:03:41 UTC
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 ***