Boost logo

Boost :

From: David Abrahams (dave_at_[hidden])
Date: 2007-06-23 18:14:00


on Fri Jun 15 2007, Eric Niebler <eric-AT-boost-consulting.com> wrote:

> David Abrahams wrote:
>> on Thu Jun 14 2007, Eric Niebler <eric-AT-boost-consulting.com> wrote:
>>> Does that really change anything? Imagine replacing the reference
>>> with a const pointer, and the potential for an ODR violation becomes
>>> more obvious:
>>>
>>> template<typename T> struct static_const
>>> {
>>> static T const value;
>>> };
>>>
>>> template<typename T>
>>> T const static_const<T>::value = {};
>>>
>>> struct placeholder {};
>>>
>>> namespace
>>> {
>>> placeholder const *const _1 = &static_const<placeholder>::value;
>>> }
>>>
>>> template<class T> void foo(T const &)
>>> {
>>> // use *_1 here. Even though *_1 refers to the same
>>> // object, we're indirecting through a different pointer
>>> // in different TUs. ODR violation?
>>> }
>>>
>>> Since you're indirecting through a different pointer, the code
>>> generated for foo() would be different in different translation
>>> units. Isn't that a violation of the ODR?
>>
>> The difference is that the references themselves do not have an
>> address.
>
> Well, I don't think this is strictly true. You can't /take/ its address,
> but that doesn't mean that a reference doesn't have one. It may very
> well occupy space, and therefore have an address. As Mike Miller said in
> response to your question:
>
> > The conceptual model of references is that they behave just like
> > objects with respect to linkage and order of initialization. This
> > allows (but does not require) them to be implemented as const
> > pointers with implicit indirection.
>
> So as far as the standard is concerned (and as far as I understand it),
> "reference == const pointer" is a good approximation.

Yes, from a conceptual/implementation POV. However, whether it's a
violation of standard rules or not has to rest on standard wording and
definitions, and AFAICT there's no support in the standard for the
view that a reference is an object.

>> The address is the only feature of those two const pointers
>> that makes them observably distinct. The core gods, of course, may
>> still disagree :-)
>
> I dug back into the standard, and I see in 3.2/5, referring to an inline
> function D with external linkage, which may appear in multiple
> translation units...
>
>> in each definition of D, corresponding names, looked up according
>> to 3.4, shall refer to an entity defined within the definition of
>> D, or shall refer to the same entity,
>
> Which made me wonder, if _1 is a reference, what is the "entity" it
> refers to? If a reference is really a pointer with implicit indirection,
> I could imagine that the "entity" is actually the pointer rather than
> the object pointed to,

How could you imagine that?

> which would be trouble. But no ... in 3/3, I see:
>
>> 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.
>
> A reference is not an entity. Whew. So I think we're ok.

Yep, I think you are seeing things the same way as I am.

IMO if the core gods want to make this an ODR violation they're going
to have to change standard language to do so :).

-- 
Dave Abrahams
Boost Consulting
http://www.boost-consulting.com
The Astoria Seminar ==> http://www.astoriaseminar.com

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