Boost logo

Boost :

From: Eric Niebler (eric_at_[hidden])
Date: 2007-06-15 02:09:28


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.

> 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, 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.

-- 
Eric Niebler
Boost Consulting
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