This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[WWW PATCH] [PR14618] Document new access checking performed by g++
- From: "Giovanni Bajo" <giovannibajo at libero dot it>
- To: <gcc-patches at gcc dot gnu dot org>
- Cc: <gdr at gcc dot gnu dot org>,"Gerald Pfeifer" <gerald at pfeifer dot com>
- Date: Thu, 18 Mar 2004 03:09:54 +0100
- Subject: [WWW PATCH] [PR14618] Document new access checking performed by g++
Hello,
as suggested by Gaby, this patch documents the new access checking performed by
g++ while binding rvalue to const references. This is strictly standard
conformant, but no compilers in my personal collection enforce this, not even
EDG-based ones. Since we already got two or three reports in a couple of weeks,
I'm adding this to both the common invalid bug list and changes.html.
Validated XHTML 1.0, OK to commit?
Giovanni Bajo
Index: bugs.html
===================================================================
RCS file: /cvs/gcc/wwwdocs/htdocs/bugs.html,v
retrieving revision 1.82
diff -c -3 -p -r1.82 bugs.html
*** bugs.html 13 Jan 2004 17:36:40 -0000 1.82
--- bugs.html 18 Mar 2004 02:03:36 -0000
*************** a parse error before the character <code
*** 685,690 ****
--- 685,735 ----
<p>The simplest way to avoid this is to write <code>std::vector<
::X></code>, i.e. place a space between the opening angle bracket
and the scope operator.</p></dd>
+
+
+ <dt><a name="known_cxx_rvalbind">Copy constructor access check while
+ initializing a reference.</a></dt>
+
+ <dd><p>Consider this code:</p>
+
+ <blockquote><pre>
+ class A
+ {
+ public:
+ A();
+
+ private:
+ A(const A& ); // private copy ctor
+ };
+
+ A makeA(void);
+ void foo(const A& a);
+
+ void bar(void)
+ {
+ foo(A()); // error, copy ctor is not accessible
+ foo(makeA()); // error, copy ctor is not accessible
+
+ A a1 = A();
+ foo(a1); // OK, a1 is a lvalue
+ A a2(makeA());
+ foo(a2); // OK, a2 is a lvalue
+ }</pre></blockquote>
+
+ <p>Starting from GCC 3.4.0, binding a rvalue to a const reference requires
+ an accessible copy constructor. This might be surprising at first sight,
+ especially since most popular compilers do not implement correctly this
+ rule.</p>
+
+ <p>The C++ Standard says that a temporary object should be created in
+ this context and its contents filled with a copy of the object we are
+ trying to bind to the reference; it also says that the temporary copy
+ can be elided, but the semantic constraints (eg. accessibility) of the
+ copy constructor still have to be checked.</p>
+
+ <p>For further information, you can consult the following paragraph of
+ the C++ standard: [dcl.init.ref]/5, bullet 2, sub-bullet 1, and
+ [class.temporary]/2.</p></dd>
</dl>
<h3><a name="upgrading">Common problems when upgrading the compiler</a></h3>
Index: gcc-3.4/changes.html
===================================================================
RCS file: /cvs/gcc/wwwdocs/htdocs/gcc-3.4/changes.html,v
retrieving revision 1.104
diff -c -3 -p -r1.104 changes.html
*** gcc-3.4/changes.html 15 Mar 2004 08:19:12 -0000 1.104
--- gcc-3.4/changes.html 18 Mar 2004 02:03:37 -0000
***************
*** 534,539 ****
--- 534,571 ----
<pre>
int* a = new (int)[10]; // error, not accepted anymore
int* a = new int[10]; // OK</pre></li>
+
+ <li>When binding a rvalue of class type to a reference, the copy
+ constructor of the class must be accessible. For instance, consider
+ the following code:
+ <pre>
+ class A
+ {
+ public:
+ A();
+
+ private:
+ A(const A& ); // private copy ctor
+ };
+
+ A makeA(void);
+ void foo(const A& a);
+
+ void bar(void)
+ {
+ foo(A()); // error, copy ctor is not accessible
+ foo(makeA()); // error, copy ctor is not accessible
+
+ A a1 = A();
+ foo(a1); // OK, a1 is a lvalue
+ A a2(makeA());
+ foo(a2); // OK, a2 is a lvalue
+ }</pre>
+
+ This might be surprising at first sight, especially since most
+ popular compilers do not implement correctly this rule. Please,
+ consult <a href="http://gcc.gnu.org/bugs.html#known_cxx_rvalbind">
+ this page</a> for a more exhaustive explanation of this non-bug.</li>
</ul>
<h3>Objective-C</h3>