diff mbox

[wwwdocs] Add a case to porting_to + a question wrt validity of another one

Message ID 20170207132747.GE13736@redhat.com
State New
Headers show

Commit Message

Marek Polacek Feb. 7, 2017, 1:27 p.m. UTC
> You could drop the namespace. Also "struct A" would be better, because
> otherwise fn1 is a private and thus unaccessible in fn2.

True.  So how about this extended version, which also mentions more examples
of what might now fail?


	Marek

Comments

Jonathan Wakely Feb. 7, 2017, 1:44 p.m. UTC | #1
On 07/02/17 14:27 +0100, Marek Polacek wrote:
>> You could drop the namespace. Also "struct A" would be better, because
>> otherwise fn1 is a private and thus unaccessible in fn2.
>
>True.  So how about this extended version, which also mentions more examples
>of what might now fail?
>
>Index: porting_to.html
>===================================================================
>RCS file: /cvs/gcc/wwwdocs/htdocs/gcc-7/porting_to.html,v
>retrieving revision 1.3
>diff -u -r1.3 porting_to.html
>--- porting_to.html	3 Feb 2017 07:55:27 -0000	1.3
>+++ porting_to.html	7 Feb 2017 13:27:28 -0000
>@@ -33,6 +33,68 @@
>
> <h2 id="cxx">C++ language issues</h2>
>
>+<h3 id="hypothetical-instantiation">Stricter rules when using templates</h3>
>+
>+<p>
>+GCC 7 no longer accepts various ill-formed code involving use of templates.
>+The C++ standard says:
>+</p>
>+
>+<p><em>
>+14.6/8: "If a hypothetical instantiation of a template immediately
>+following its definition would be ill-formed due to a construct that
>+does not depend on a template parameter, the program is ill-formed; no
>+diagnostic is required.  If the interpretation of such a construct in
>+the hypothetical instantiation is different from the interpretation of
>+the corresponding construct in any actual instantiation of the
>+template, the program is ill-formed; no diagnostic is required."
>+</em></p>
>+
>+<p>
>+As a consequence, the following examples are now invalid and G++ will no longer

I'd remove "now" since they've always been invalid, we just didn't
diagnose them until now.

>+compile them:
>+<pre><code>
>+struct C;
>+struct A {
>+  C fn1();
>+};
>+template &lt;typename&gt; class B : A {
>+  void fn2() { fn1().x; }
>+};
>+</code></pre>
>+will result in
>+<blockquote><pre>
>+<span class="boldred">error:</span> invalid use of incomplete type <b>'struct C'</b>
>+</pre></blockquote>
>+
>+<pre><code>
>+class A {

Make this a struct, not a class. Otherwise the code would also be
invalid because of an access error, which isn't relevant to the
example.

>+  int m_class;

I suggest changing "m_class" (in both places) to something more
generic, like "m_val" or just "x". And "m_fn1" is a funny member
function name, "fn1" (as in the previous example) would be better.

>+};
>+template &lt;class&gt; class B : A { void m_fn1(); };

Unless you want to vary the examples intentionally, I'd change "<class>"
to "<typename>" for consistency with the other two examples. The
fewer unrelated differences between the examples the better, so users
don't waste time wondering if the unrelated differences are
significant to the example.

>+template &lt;class T&gt; void B&lt;T&gt;::m_fn1() { foo (this-&gt;m_class); }

This function could be defined inline, as in the previous example.
Whether it's defined out of the class body isn't relevant.

So simply:

struct A {
  int x;
};
template<typename> struct B : A {
  void fn1() { foo (this->x); }
};


>+</code></pre>
>+will result in
>+<blockquote><pre>
>+<span class="boldred">error:</span> there are no arguments to <b>'foo'</b> that depend on a template parameter, so a declaration of <b>'foo'</b> must be available
>+</pre></blockquote>
>+
>+<pre><code>
>+class A {

This can be a struct again.

>+  void *a;

Idiomatic C++ would say "void* a" not "void *a" but you could use
"void * a" to keep both groups of people happy ;-)

>+};
>+template &lt;typename&gt; class B : A {
>+  void m_fn1() { this-&gt;a[0]; }

s/m_fn1/fn1/ again
diff mbox

Patch

Index: porting_to.html
===================================================================
RCS file: /cvs/gcc/wwwdocs/htdocs/gcc-7/porting_to.html,v
retrieving revision 1.3
diff -u -r1.3 porting_to.html
--- porting_to.html	3 Feb 2017 07:55:27 -0000	1.3
+++ porting_to.html	7 Feb 2017 13:27:28 -0000
@@ -33,6 +33,68 @@ 
 
 <h2 id="cxx">C++ language issues</h2>
 
+<h3 id="hypothetical-instantiation">Stricter rules when using templates</h3>
+
+<p>
+GCC 7 no longer accepts various ill-formed code involving use of templates.
+The C++ standard says:
+</p>
+
+<p><em>
+14.6/8: "If a hypothetical instantiation of a template immediately
+following its definition would be ill-formed due to a construct that
+does not depend on a template parameter, the program is ill-formed; no
+diagnostic is required.  If the interpretation of such a construct in
+the hypothetical instantiation is different from the interpretation of
+the corresponding construct in any actual instantiation of the
+template, the program is ill-formed; no diagnostic is required."
+</em></p>
+
+<p>
+As a consequence, the following examples are now invalid and G++ will no longer
+compile them:
+<pre><code>
+struct C;
+struct A {
+  C fn1();
+};
+template &lt;typename&gt; class B : A {
+  void fn2() { fn1().x; }
+};
+</code></pre>
+will result in
+<blockquote><pre>
+<span class="boldred">error:</span> invalid use of incomplete type <b>'struct C'</b>
+</pre></blockquote>
+
+<pre><code>
+class A {
+  int m_class;
+};
+template &lt;class&gt; class B : A { void m_fn1(); };
+template &lt;class T&gt; void B&lt;T&gt;::m_fn1() { foo (this-&gt;m_class); }
+</code></pre>
+will result in
+<blockquote><pre>
+<span class="boldred">error:</span> there are no arguments to <b>'foo'</b> that depend on a template parameter, so a declaration of <b>'foo'</b> must be available
+</pre></blockquote>
+
+<pre><code>
+class A {
+  void *a;
+};
+template &lt;typename&gt; class B : A {
+  void m_fn1() { this-&gt;a[0]; }
+};
+</code></pre>
+will result in
+<blockquote><pre>
+<span class="boldred">error:</span> <b>'void*'</b> is not a pointer-to-object type
+</pre></blockquote>
+because there's no instantiation of that template that can be valid, it will
+always dereference a <code>void*</code>.
+</p>
+
 <h3 id="conversion-op-mangling">Mangling change for conversion operators</h3>
 
 <p>