Boost logo

Boost :

From: Ian McCulloch (ianmcc_at_[hidden])
Date: 2004-05-08 01:07:17


David Abrahams wrote:

> Ian McCulloch <ianmcc_at_[hidden]> writes:
>
>> David Abrahams wrote:
>>
>>> "Arkadiy Vertleyb" <vertleyb_at_[hidden]> writes:
>>>
>>>> "David Abrahams" <dave_at_[hidden]> 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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk