There seems to be something inconsistent in the g++ template instantiation. When a template is instantiated with an argument of the same name in two object files in which the argument type is different (unlike their names). It appears that even though that those instances should have been distinct g++ resolves them into a single one which appears to be wrong. Please see the attached reproduction code. The code of the template only prints the sizeof() of its (template) argument. The argument if places in a global namespace in each of the object files is considered to be the same no matter of its size or structure (as long as it is of the same name). I have reproduced the gcc 3.4.6 and gcc 4.0.1 to behave the same in this aspect (see the attached test output files).
Created attachment 13805 [details] Reproduction code and Makefile printing out results of the test The log files gcc-4.1.0.make.log and gcc-3.4.6.make.log contain the 'make' output from RHEL 4.0 Linux machine.
I don't think this is a bug. So we have in one TU: typedef struct { char x[10]; } Argument; And in the other: typedef struct { char x[20]; } Argument; --------------- cut --------------- IIRC from my reading of the C++ standard, that Argument here has to be same types accross TUs (the One Definition Rule).
I am not sure about the standard wording. But logically typedefs local to a .cpp file should stay local to that file. They in fact are. However the template instances are not. If it should not be that way then the compiler should complain about such conflicts in some way not to get the two confused at runtime. Especially in huge application merges this is very critical. note: I am sorry, will be out of reach for the next few weeks to discuss in detail. I would appreciate any pointers or more detailed explanations you could provide.
The code is definitely invalid. The two typedefs declare two types with external linkage. This is an ODR violation making the code invalid. The standard doesn't require compilers to produce an error for a very good reason: it is almost impossible to detect this without support from a linker that understands all wrinkles and depths of the C++ language.
Yes, I have checked the ODR definition and it is really the fact that the code violates that. Thank you for your explanations.