
David Abrahams wrote:
Ian McCulloch <ianmcc@lorentz.leidenuniv.nl> writes:
David Abrahams wrote:
"Arkadiy Vertleyb" <vertleyb@hotmail.com> writes:
"David Abrahams" <dave@boost-consulting.com> wrote
Any time a template is instantitated, all names in its definition must map to the same entities in each translation unit, or you violate the ODR. By definition, names in the unnamed namespace refer to distinct entities in each translation unit.
But typedef only introduces aliases for an existing type. Does that qualify for "map[s] onto the same entity" ?
Your question isn't specific enough for me to answer.
Sorry, I meant: do two typedefs that are aliases for the same type, but differ in name, count as different entities with respect to the ODR? This is defined in 3 [basic]: -3- An "entity" is a value, object, subobject, base class subobject, array element, variable, function, instance of a function, enumerator, type, class member, template or namespace. This doesn't include typedef names, but doesn't specifically exclude them either. Moving onto 7.1.3 The typedef specifier: -1- ... (sorry, I cannot cut&paste from my (old) copy of the stamdard) A name declared with the"typedef" specifier becomes a typedef-name. Within the scope of its definition, a typedef-name is syntactially equivalent to a keyword and names the type associated with the identifier in the way described in clause 8. A typedef-name is thus a synonym for another type. A typedef-name does not introduce a new type in the way a class declaratin (9.1) or enum declaration does. [Example: after typedef int MILES, *KLICKSP; the constructions MILES distance; extern KLICKSP metricp; are all correct declarations; the type of distance is int; that of metricp is "pointer to int."] -- end quote Following on from the example, I take this to mean one translation unit declaring "extern int* metricp" and another declaring "extern KLICKSP metricp" is not an ODR violation. Similarly, declaring KLICKSP in an unnamed namespace in a header file should be OK too.
IOW, such templates in different translation units will be absolutely the same, although in each translation unit the compiler will have to instantiate different intermediate classes in order to produce them.
Those intermediate classes are in an unnamed namespace and not an ODR violation in themselves?
Not in and of themselves. Their use in the same template in multiple translation units is a violation, IIUC.
If I understand correctly, you are saying that
// header.h namespace { typedef int foo; }
struct bar { foo f; };
// end header.h
causes an ODR violation if type bar (or even foo) is used in more than one translation unit?
That appears to be clearly spelled out below. AFAICT unnamed namespaces in header files are evil.
Can you quote chapter and verse? (or perhaps that should be asked on c.s.c++).
Probably ;-) It's all there right under "One definition rule" in the standard.
3 Basic concepts 3.2 One definition rule
-5- There can be more than one definition of a class type (clause class), enumeration type (dcl.enum), inline function with external linkage (dcl.fct.spec), class template (clause temp), non-static function template (temp.fct), static data member of a class template (temp.static), member function [core 249: template of a class template ] (temp.mem.func), or template specialization for which some template parameters are not specified (temp.spec, temp.class.spec) in a program provided that each definition appears in a different translation unit, and provided the definitions satisfy the following requirements. Given such an entity named D defined in more than one translation unit, then
- each definition of D shall consist of the same sequence of tokens; and
- in each definition of D, corresponding names, looked up according to basic.lookup, shall refer to an entity defined within the definition of D, or shall refer to the same entity, after ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
To my reading of the standard, different typedef-names that are synonyms for the same type are the same entity with respect to the ODR, so I don't think any of this applies here. Cheers, Ian McCulloch