diff mbox series

wwwdocs: gcc-15: start adding notes on C23

Message ID 20241209194442.3154998-1-dmalcolm@redhat.com
State New
Headers show
Series wwwdocs: gcc-15: start adding notes on C23 | expand

Commit Message

David Malcolm Dec. 9, 2024, 7:44 p.m. UTC
How does this look?

Thanks
Dave

---
 htdocs/gcc-15/changes.html    | 12 ++++++++++++
 htdocs/gcc-15/porting_to.html | 34 +++++++++++++++++++++++++++++++++-
 2 files changed, 45 insertions(+), 1 deletion(-)

Comments

Jakub Jelinek Dec. 9, 2024, 7:58 p.m. UTC | #1
On Mon, Dec 09, 2024 at 02:44:42PM -0500, David Malcolm wrote:
> +C23 brings the following changes:
> +
> +<h4 id="c23-empty-fn-prototypes-become-void">Function prototypes with empty params change from implicit <code>int</code> to <code>void</code></h4>
> +
> +<p> In C23 <code>()</code> in a function declaration means the same as <code>(void)</code>, whereas previously it implicitly declared the function to take an <code>int</code> parameter.</p>

This isn't true.  void foo (); used to be an unprototyped function,
one could pass any arguments to it (of course without invoking UB
only if it actually matched the arguments passed to it).
So, with
void foo ();
int bar ();
one can
  foo (1, 2.0, 3L, bar (2));
if the definitions were
void foo (int a, double b, long c, int d) {
//...
}
int bar (int e) {
//...
}
or K&R-ish
void foo (f, g, h, i)
  int f;
  double g;
  long h;
  int i;
{
/* ... */
}
void bar (j)
  int j;
{
/* ... */
}

Implicit int was about completely undeclared functions in K&R/C89,
those were assumed to return int.  But we already error on those by
default in C99 and later modes, so no need to describe it again.

	Jakub
David Malcolm Jan. 15, 2025, 4:32 p.m. UTC | #2
On Mon, 2024-12-09 at 20:58 +0100, Jakub Jelinek wrote:
> On Mon, Dec 09, 2024 at 02:44:42PM -0500, David Malcolm wrote:
> > +C23 brings the following changes:
> > +
> > +<h4 id="c23-empty-fn-prototypes-become-void">Function prototypes
> > with empty params change from implicit <code>int</code> to
> > <code>void</code></h4>
> > +
> > +<p> In C23 <code>()</code> in a function declaration means the
> > same as <code>(void)</code>, whereas previously it implicitly
> > declared the function to take an <code>int</code> parameter.</p>
> 
> This isn't true.  void foo (); used to be an unprototyped function,
> one could pass any arguments to it (of course without invoking UB
> only if it actually matched the arguments passed to it).
> So, with
> void foo ();
> int bar ();
> one can
>   foo (1, 2.0, 3L, bar (2));
> if the definitions were
> void foo (int a, double b, long c, int d) {
> //...
> }
> int bar (int e) {
> //...
> }
> or K&R-ish
> void foo (f, g, h, i)
>   int f;
>   double g;
>   long h;
>   int i;
> {
> /* ... */
> }
> void bar (j)
>   int j;
> {
> /* ... */
> }
> 
> Implicit int was about completely undeclared functions in K&R/C89,
> those were assumed to return int.  But we already error on those by
> default in C99 and later modes, so no need to describe it again.

Here's an updated version of the patch

OK to push? (we could tweak it in followups)

I'm working on followups covering other issues that showed up in:
https://fedoraproject.org/wiki/F42-gcc-15-mass-prebuild

Thanks
Dave

 htdocs/gcc-15/changes.html    | 12 +++++++
 htdocs/gcc-15/porting_to.html | 67 ++++++++++++++++++++++++++++++++++-
 2 files changed, 78 insertions(+), 1 deletion(-)

diff --git a/htdocs/gcc-15/changes.html b/htdocs/gcc-15/changes.html
index 1c690c4a..601d7760 100644
--- a/htdocs/gcc-15/changes.html
+++ b/htdocs/gcc-15/changes.html
@@ -96,6 +96,18 @@ a work-in-progress.</p>
 	    <code>musttail</code> statement attribute</a> was added to enforce tail calls.</li>
 </ul>
 
+<h3 id="c">C</h3>
+<ul>
+  <li>GCC 15 changes the default language version for C compilation from
+    <a href="https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#index-std-1">-std=gnu17</a>
+    to
+    <a href="https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#index-std-1">-std=gnu23</a>.
+    If your code relies on older versions of the C standard, you will need to
+    either add
+    <a href="https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#index-std-1">-std=</a>
+    to your build flags, or port your code; see <a href="porting_to.html#c23">the porting notes</a>.
+</ul>
+
 <h3 id="cxx">C++</h3>
 
 <ul>
diff --git a/htdocs/gcc-15/porting_to.html b/htdocs/gcc-15/porting_to.html
index 702cf507..385fa141 100644
--- a/htdocs/gcc-15/porting_to.html
+++ b/htdocs/gcc-15/porting_to.html
@@ -27,7 +27,72 @@ and provide solutions. Let us know if you have suggestions for improvements!
 <p>Note: GCC 15 has not been released yet, so this document is
 a work-in-progress.</p>
 
-<!-- <h2 id="c">C language issues</h2> -->
+<h2 id="c">C language issues</h2>
+
+<h3 id="c23">C23 by default</h3>
+<!-- change of default was in commit 55e3bd376b2214e200fa76d12b67ff259b06c212 -->
+
+GCC 15 changes the default language version for C compilation from
+<a href="https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#index-std-1">-std=gnu17</a>
+to
+<a href="https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#index-std-1">-std=gnu23</a>.
+
+If your code relies on older versions of the C standard, you will need to
+either add <a href="https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#index-std-1">-std=</a>
+to your build flags, or port your code to C23.
+
+C23 brings the following changes:
+
+<h4 id="c23-fn-decls-without-parameters">Function declarations without parameters</h4>
+<p>
+  The meaning of function declarations of the form
+  <code>rettype identifier ();</code>
+  such as
+  <code>char *strstr ();</code>
+  that are not a definition changed in C23.
+</p>
+<p>
+  In C17 and earlier, such function declarators specified no information
+  about the number or types of the parameters of the function (C17 6.7.6.3),
+  requiring users to know the correct number of arguments, with each passed
+  argument going through default argument promotion.
+</p>
+<p>
+  In C23 such declarations mean <code>(void)</code> i.e. a function taking
+  no arguments, which can lead to build failures on code that relied on
+  the earlier meaning, such as in
+  <a href="https://godbolt.org/z/11hzWYEeK">this example</a>:
+</p>
+<pre><code>
+#include &lt;signal.h&gt;
+
+void test()
+{
+  void (*handler)();
+  handler = signal(SIGQUIT, SIG_IGN);
+}
+
+&lt;source&gt;: In function 'test':
+&lt;source&gt;:6:11: error: assignment to 'void (*)(void)' from incompatible pointer type '__sighandler_t' {aka 'void (*)(int)'} [-Wincompatible-pointer-types]
+    6 |   handler = signal(SIGQUIT, SIG_IGN);
+      |           ^
+In file included from &lt;source&gt;:1:
+/usr/include/signal.h:72:16: note: '__sighandler_t' declared here
+   72 | typedef void (*__sighandler_t) (int);
+      |                ^~~~~~~~~~~~~~
+</code></pre>
+<p>
+  Code relying on a non-zero number of parameters (such as a single
+  <code>int</code>) can be fixed for C23 by adding the correct parameters
+  to the function declarator, such as in the above via:
+</p>
+<pre><code>
+  void (*handler)(int);
+</code></pre>
+<p>
+  or you can use <a href="https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#index-std-1">-std=</a>
+  to select an earlier version of the C standard.
+</p>
 
 <h2 id="cxx">C++ language issues</h2>
Joseph Myers Jan. 15, 2025, 6:22 p.m. UTC | #3
On Wed, 15 Jan 2025, David Malcolm wrote:

> Here's an updated version of the patch
> 
> OK to push? (we could tweak it in followups)

This will need updating to work together with Jakub's patch that also adds 
the C section to changes.html.

> +<h4 id="c23-fn-decls-without-parameters">Function declarations without parameters</h4>
> +<p>
> +  The meaning of function declarations of the form
> +  <code>rettype identifier ();</code>
> +  such as
> +  <code>char *strstr ();</code>
> +  that are not a definition changed in C23.
> +</p>

It's not limited to "not a definition", it also introduces a prototype 
(for calls following the definition) for () in a definition as well, where 
there wasn't one before.

> +<p>
> +  Code relying on a non-zero number of parameters (such as a single
> +  <code>int</code>) can be fixed for C23 by adding the correct parameters
> +  to the function declarator, such as in the above via:
> +</p>
> +<pre><code>
> +  void (*handler)(int);
> +</code></pre>
> +<p>
> +  or you can use <a href="https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#index-std-1">-std=</a>
> +  to select an earlier version of the C standard.
> +</p>

Maybe also mention the case where the function already has a prototype in 
some header (standard or in the project) and you can just remove the 
non-prototype declaration and make sure to include the header?  This is 
for legacy code that does things like

void *malloc();

with its own declarations of standard functions, you may have a better 
idea of how common that is.
David Malcolm Jan. 15, 2025, 7:20 p.m. UTC | #4
On Wed, 2025-01-15 at 18:22 +0000, Joseph Myers wrote:
> On Wed, 15 Jan 2025, David Malcolm wrote:
> 
> > Here's an updated version of the patch
> > 
> > OK to push? (we could tweak it in followups)
> 
> This will need updating to work together with Jakub's patch that also
> adds 
> the C section to changes.html.

For now I've pushed this part of the patch:

diff --git a/htdocs/gcc-15/changes.html b/htdocs/gcc-15/changes.html
index d5037efb..c87c8a0d 100644
--- a/htdocs/gcc-15/changes.html
+++ b/htdocs/gcc-15/changes.html
@@ -99,6 +99,18 @@ a work-in-progress.</p>
 	    <code>musttail</code> statement attribute</a> was added to enforce tail calls.</li>
 </ul>
 
+<h3 id="c">C</h3>
+<ul>
+  <li>GCC 15 changes the default language version for C compilation from
+    <a href="https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#index-std-1">-std=gnu17</a>
+    to
+    <a href="https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#index-std-1">-std=gnu23</a>.
+    If your code relies on older versions of the C standard, you will need to
+    either add
+    <a href="https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#index-std-1">-std=</a>
+    to your build flags, or port your code; see <a href="porting_to.html#c23">the porting notes</a>.
+</ul>
+
 <h3 id="cxx">C++</h3>
 
 <ul>
David Malcolm Jan. 15, 2025, 8:07 p.m. UTC | #5
On Wed, 2025-01-15 at 18:22 +0000, Joseph Myers wrote:
> On Wed, 15 Jan 2025, David Malcolm wrote:
> 
> > Here's an updated version of the patch
> > 
> > OK to push? (we could tweak it in followups)
> 
> This will need updating to work together with Jakub's patch that also
> adds 
> the C section to changes.html.
> 
> > +<h4 id="c23-fn-decls-without-parameters">Function declarations
> > without parameters</h4>
> > +<p>
> > +  The meaning of function declarations of the form
> > +  <code>rettype identifier ();</code>
> > +  such as
> > +  <code>char *strstr ();</code>
> > +  that are not a definition changed in C23.
> > +</p>
> 
> It's not limited to "not a definition", it also introduces a
> prototype 
> (for calls following the definition) for () in a definition as well,
> where 
> there wasn't one before.
> 
> > +<p>
> > +  Code relying on a non-zero number of parameters (such as a
> > single
> > +  <code>int</code>) can be fixed for C23 by adding the correct
> > parameters
> > +  to the function declarator, such as in the above via:
> > +</p>
> > +<pre><code>
> > +  void (*handler)(int);
> > +</code></pre>
> > +<p>
> > +  or you can use <a
> > href="https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#ind
> > ex-std-1">-std=</a>
> > +  to select an earlier version of the C standard.
> > +</p>
> 
> Maybe also mention the case where the function already has a
> prototype in 
> some header (standard or in the project) and you can just remove the 
> non-prototype declaration and make sure to include the header?  This
> is 
> for legacy code that does things like
> 
> void *malloc();
> 
> with its own declarations of standard functions, you may have a
> better 
> idea of how common that is.
> 

Thanks.  I've tweaked for the above and taken the liberty of pushing
the following (in the hope of not letting "perfect be the enemy of the
good").  If I've still got the wording wrong, can someone with better
knowledge of C standards fix it, please.

---
 htdocs/gcc-15/porting_to.html | 64 ++++++++++++++++++++++++++++++++++-
 1 file changed, 63 insertions(+), 1 deletion(-)

diff --git a/htdocs/gcc-15/porting_to.html b/htdocs/gcc-15/porting_to.html
index 39598b93..c446e309 100644
--- a/htdocs/gcc-15/porting_to.html
+++ b/htdocs/gcc-15/porting_to.html
@@ -41,7 +41,69 @@ If your code relies on older versions of the C standard, you will need to
 either add <a href="https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#index-std-1">-std=</a>
 to your build flags, or port your code to C23.
 
-<!-- C23 brings the following changes: -->
+C23 brings the following changes:
+
+<h4 id="c23-fn-decls-without-parameters">Function declarations without parameters</h4>
+<p>
+  The meaning of function declarations of the form
+  <code>rettype identifier ();</code>
+  such as
+  <code>char *strstr ();</code>
+  changed in C23.
+</p>
+<p>
+  In C17 and earlier, such function declarators specified no information
+  about the number or types of the parameters of the function (C17 6.7.6.3),
+  requiring users to know the correct number of arguments, with each passed
+  argument going through default argument promotion.
+</p>
+<p>
+  In C23 such declarations mean <code>(void)</code> i.e. a function taking
+  no arguments, which can lead to build failures on code that relied on
+  the earlier meaning, such as in
+  <a href="https://godbolt.org/z/11hzWYEeK">this example</a>:
+</p>
+<pre><code>
+#include &lt;signal.h&gt;
+
+void test()
+{
+  void (*handler)();
+  handler = signal(SIGQUIT, SIG_IGN);
+}
+
+&lt;source&gt;: In function 'test':
+&lt;source&gt;:6:11: error: assignment to 'void (*)(void)' from incompatible pointer type '__sighandler_t' {aka 'void (*)(int)'} [-Wincompatible-pointer-types]
+    6 |   handler = signal(SIGQUIT, SIG_IGN);
+      |           ^
+In file included from &lt;source&gt;:1:
+/usr/include/signal.h:72:16: note: '__sighandler_t' declared here
+   72 | typedef void (*__sighandler_t) (int);
+      |                ^~~~~~~~~~~~~~
+</code></pre>
+<p>
+  Code such as the above relying on a non-zero number of parameters (such
+  as a single <code>int</code>) can be fixed for C23 by adding the correct
+  parameters to the function declarator, such as via:
+</p>
+<pre><code>
+  void (*handler)(int);
+</code></pre>
+<p>
+  In other cases the code is simply missing a <code>#include</code> of
+  the correct header, such as with:
+<pre><code>
+  void *malloc();
+</code></pre>
+<p>
+  These can be fixed by including the correct header and removing the
+  non-prototype declaration.
+</p>
+<p>
+  Alternatively you can use
+  <a href="https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#index-std-1">-std=</a>
+  to select an earlier version of the C standard.
+</p>
 
 <h4 id="c23-new-keywords">New keywords</h4>
 <p>
diff mbox series

Patch

diff --git a/htdocs/gcc-15/changes.html b/htdocs/gcc-15/changes.html
index 23866bde..94731f55 100644
--- a/htdocs/gcc-15/changes.html
+++ b/htdocs/gcc-15/changes.html
@@ -96,6 +96,18 @@  a work-in-progress.</p>
 	    <code>musttail</code> statement attribute</a> was added to enforce tail calls.</li>
 </ul>
 
+<h3 id="c">C</h3>
+<ul>
+  <li>GCC 15 changes the default language version for C compilation from
+    <a href="https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#index-std-1">-std=gnu17</a>
+    to
+    <a href="https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#index-std-1">-std=gnu23</a>.
+    If your code relies on older versions of the C standard, you will need to
+    either add
+    <a href="https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#index-std-1">-std=</a>
+    to your build flags, or port your code; see <a href="porting_to.html#c23">the porting notes</a>.
+</ul>
+
 <h3 id="cxx">C++</h3>
 
 <ul>
diff --git a/htdocs/gcc-15/porting_to.html b/htdocs/gcc-15/porting_to.html
index 702cf507..2c9dce68 100644
--- a/htdocs/gcc-15/porting_to.html
+++ b/htdocs/gcc-15/porting_to.html
@@ -27,7 +27,39 @@  and provide solutions. Let us know if you have suggestions for improvements!
 <p>Note: GCC 15 has not been released yet, so this document is
 a work-in-progress.</p>
 
-<!-- <h2 id="c">C language issues</h2> -->
+<h2 id="c">C language issues</h2>
+
+<h3 id="c23">C23 by default</h3>
+<!-- change of default was in commit 55e3bd376b2214e200fa76d12b67ff259b06c212 -->
+
+GCC 15 changes the default language version for C compilation from
+<a href="https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#index-std-1">-std=gnu17</a>
+to
+<a href="https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#index-std-1">-std=gnu23</a>.
+
+If your code relies on older versions of the C standard, you will need to
+either add <a href="https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#index-std-1">-std=</a>
+to your build flags, or port your code.
+
+C23 brings the following changes:
+
+<h4 id="c23-empty-fn-prototypes-become-void">Function prototypes with empty params change from implicit <code>int</code> to <code>void</code></h4>
+
+<p> In C23 <code>()</code> in a function declaration means the same as <code>(void)</code>, whereas previously it implicitly declared the function to take an <code>int</code> parameter.</p>
+
+<p>Hence
+
+<code>extern int foo();</code>
+
+now means
+
+<code>extern int foo(void);</code>
+
+rather than
+
+<code>extern int foo(int);</code>
+
+<p>Code relying on an implicit <code>int</code> param declaration can be fixed for C23 by adding an explicit <code>int</code> to the function prototype, or you can use <a href="https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#index-std-1">-std=</a> to select an earlier version of the C standard.</p>
 
 <h2 id="cxx">C++ language issues</h2>