This is really a problem that arises *because* g++ implements the standard. I have tried to raise this as a DR, but to no avail. Subject: Defect Report: reference-compatible is defined too narrowly in [decl.int.ref] Date: Mon, 07 Feb 2005 17:33:41 +0000 From: Joern Rennecke <joern.rennecke@st.com> To: std-c++@ncar.ucar.edu 8.5.3 [decl.int.ref] Paragraph 4 defines reference-compatible so narrowly that "const int * const" is not reference-compatible to "int * const" . As a result, for this program: extern void abort (void); int i0 = 999; int *const p = &i0; const int *const & foo () { return p; } int main () { int i = *foo (); if (i != i0) abort (); return 0; } only the last item of 8.5.3 Paragraph 5 that applies to the return value of foo, and hence foo is translated as if it was written as: const int *const & foo () { int const *const p0 = p; return p0; } I.e. the reference is bound to a temporary that lives only lives till foo exits (in accordance with 12.2 [class.temporary] Paragraph 5). Thus, using the value of *foo () invokes undefined behaviour. The programmer will more likely expect foo to behave like it was written: const int *const & foo () { const int *const *p0 = &p; return *p0; } This works because the last item of 8.5.3 paragraph 14 applies, i.e. standard conversions apply. We can't convert to the cv-unqualified version of the destination type, but that is not necessary since we can convert to the cv-qualified destination type according to 4.4 [conv.qual] paragraph 4. I think similar language to 4.4 paragraph 4 should be added to the definition of reference compatibility in 8.5.3. This could possibly combined with array type declarators as alternatives to 'pointer to' to also address DR 450.
Daniel, are you willing to have a look to this issue? Time to resolve it one way or another!
To be honest, I don't know if something changed lately in the ISO Standard about this, but really, doesn't look like a GCC issue. In case, you may consider also using comp.std.c++.moderated if not the reflectors.
A new core issue has been opened for this problem: http://www.open-std.org/jtc1/sc22/wg21/prot/14882fdis/cwg_active.html#1401
the public version is at http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1401