Bug 29859 - reference-compatible is defined too narrowly in [decl.int.ref]
Summary: reference-compatible is defined too narrowly in [decl.int.ref]
Status: RESOLVED INVALID
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: 4.3.0
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks: 29842
  Show dependency treegraph
 
Reported: 2006-11-15 23:10 UTC by Jorn Wolfgang Rennecke
Modified: 2012-01-19 19:32 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Jorn Wolfgang Rennecke 2006-11-15 23:10:59 UTC
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.
Comment 1 Paolo Carlini 2011-09-29 23:16:13 UTC
Daniel, are you willing to have a look to this issue? Time to resolve it one way or another!
Comment 2 Paolo Carlini 2011-10-16 15:19:46 UTC
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.
Comment 3 Daniel Krügler 2012-01-19 19:01:20 UTC
A new core issue has been opened for this problem:

http://www.open-std.org/jtc1/sc22/wg21/prot/14882fdis/cwg_active.html#1401
Comment 4 Jonathan Wakely 2012-01-19 19:32:41 UTC
the public version is at http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1401