From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2178) id B3CB03858D33; Sat, 17 Feb 2024 09:25:46 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org B3CB03858D33 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1708161946; bh=w0fqQMD8u7DsAyLxtozNaC5eAdqzxMs/x0PzFMWjZkc=; h=To:Subject:Date:From:From; b=cATyXlsJRCzq99s/sK2dNkYc4XtExV7PW4NxbKIR7rNlUFgRPFOLOm7Qku22GywEu V2sxuWgRYOV4aG/PfG1MF2HSykHJExy78eg6VGqePUWKLxkloNfwjGPz+6eD5M0ZoB 05DEsD4vRuUbppZ7d2KI+PUDTxJHNfK6E2ahskzQ= To: gcc-cvs-wwwdocs@gcc.gnu.org Subject: gcc-wwwdocs branch master updated. 848ebfb46379178be3b0307c2ef99f4012e40edd X-Git-Refname: refs/heads/master X-Git-Reftype: branch X-Git-Oldrev: 3ecd137ec06d53b5f3f059df2a108274a7f894d2 X-Git-Newrev: 848ebfb46379178be3b0307c2ef99f4012e40edd Message-Id: <20240217092546.B3CB03858D33@sourceware.org> Date: Sat, 17 Feb 2024 09:25:46 +0000 (GMT) From: Florian Weimer List-Id: This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "gcc-wwwdocs". The branch, master has been updated via 848ebfb46379178be3b0307c2ef99f4012e40edd (commit) from 3ecd137ec06d53b5f3f059df2a108274a7f894d2 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 848ebfb46379178be3b0307c2ef99f4012e40edd Author: Florian Weimer Date: Sat Feb 17 10:25:18 2024 +0100 gcc-14: Notes on the warnings-as-errors change diff --git a/htdocs/gcc-14/porting_to.html b/htdocs/gcc-14/porting_to.html index 3e4cedc3..bbbaa25a 100644 --- a/htdocs/gcc-14/porting_to.html +++ b/htdocs/gcc-14/porting_to.html @@ -24,6 +24,472 @@ porting to GCC 14. This document is an effort to identify common issues and provide solutions. Let us know if you have suggestions for improvements!

+

C language issues

+ +

Certain warnings are now errors

+ +
+ Function prototyping was added, first to help enforce type checking + on both the types of the arguments passed to the function, and also + to check the assignment compatibility of the function return type. +
+ Standard C: The ANSI Draft Grows Up. + PC Magazine, September 13, 1988, page 117. +
+
+ +The initial ISO C standard and its 1999 revision removed support for +many C language features that were widely known as sources of +application bugs due to accidental misuse. For backwards +compatibility, GCC 13 and earlier diagnosed use of +these features as warnings only. Although these warnings have been +enabled by default for many releases, experience shows that these +warnings are easily ignored, resulting in difficult to diagnose bugs. +In GCC 14, these issues are now reported as errors, and no output file +is created, providing clearer feedback to programmers that something +is wrong. + +

+Most components of the GNU project have already been fixed for +compatibility, but not all of them have had releases since fixes were +applied. Programs that bundle parts +of gnulib or +autoconf-archive +may need to update these sources files from their upstream versions. + +

+Several GNU/Linux distributions have shared patches from their porting +efforts on relevant upstream mailing lists and bug trackers, but of +course many programs that exhibit these historic C compatibility +issues are dormant today. + +

Implicit int types (-Werror=implicit-int)

+ +In most cases, simply adding the missing int keyword +addresses the error. For example, a flag variable like + +
+  static initialized;
+
+ +becomes: + +
+  static int initialized;
+
+ +

If the return type of a function is omitted, the correct type to +add can be int or void, depending on +whether the function returns a value or not. + +

In some cases the previously implied int type was not +correct. This mostly happens in old-style function definitions, when +argument types are not declared outside the parameter list. Using the +correct type may be required to avoid int-conversion errors (see +below). In the example below, the type of s should be +const char *, not int: + +

+  write_string (fd, s)
+  {
+    write (1, s, strlen (s));
+  }
+
+ +The corrected standard C source code might look like this (still +disregarding error handling and short writes): + +
+  void
+  write_string (int fd, const char *s)
+  {
+    write (1, s, strlen (s));
+  }
+
+ +

Implicit function declarations (-Werror=implicit-function-declaration)

+ +It is no longer possible to call a function that has not been +declared. In general, the solution is to include a header file with +an appropriate function prototype. Note that GCC will perform further +type checks based on the function prototype, which can reveal further +type errors that require additional changes. + +

+For well-known functions declared in standard headers, GCC provides +fix-it hints with the appropriate #include directives: + +

+error: implicit declaration of function ‘strlen’ [-Wimplicit-function-declaration]
+    5 |   return strlen (s);
+      |          ^~~~~~
+note: include ‘<string.h>’ or provide a declaration of ‘strlen’
+  +++ |+#include <string.h>
+    1 |
+
+ +

+On GNU systems, headers described in standards (such as the C +standard, or POSIX) may require the definition of certain +macros at the start of the compilation before all required +function declarations are made available. +See Feature Test Macros +in the GNU C Library manual for details. + +

+Some programs are built with -std=c11 or +similar -std options that do not contain the +string gnu, but still use POSIX or other +extensions in standard C headers such as <stdio.h>. +The GNU C library automatically suppresses these extensions in +standard C mode, which can result in implicit function declarations. +To address this, the -std=c11 option can be +dropped, -std=gnu11 can be used instead, +or -std=c11 -D_DEFAULT_SOURCE can be used re-enable +common extensions. Alternatively, projects using using Autoconf +could enable AC_USE_SYSTEM_EXTENSIONS. + +

+If undeclared functions from the same project are called and there is +no suitable shared header file yet, you should add a declaration to a +header file that is included by both the callers and the source file +containing the function definition. This ensures that GCC checks that +the prototype matches the function definition. GCC can perform type +checks across translation units when building with options such as +-flto -Werror=lto-type-mismatch, which can help with +adding appropriate prototypes. + +

+In some rare cases, adding a prototype may change ABI in inappropriate +ways. In these situations, it is necessary to declare a function +without a prototype: + +

+  void no_prototype ();
+
+ +However, this is an obsolete C feature that will change meaning in C23 +(declaring a function with a prototype and accepting no arguments, +similar to C++). Usually, a prototype with the default argument +promotions applied can be used instead. + +

+When building library code on GNU systems, +it was possible to call + undefined (not just undeclared) functions +and still run other code in the library, particularly if ELF lazy binding +was used. Only executing the undefined function call would result in a +lazy binding error and program crash. + +

Typos in function prototypes (-Werror=declaration-missing-parameter-type)

+ +Incorrectly spelled type names in function declarations are treated as +errors in more cases, under a +new -Wdeclaration-missing-parameter-type warning. The +second line in the following example is now treated as an error +(previously this resulted in a warning not controlled by a specific +-W… option): + +
+  typedef int *int_array;
+  int first_element (intarray);
+
+ +The fix is to correct the spelling mistake: + +
+  typedef int *int_array;
+  int first_element (int_array);
+
+ +GCC will type-check function arguments after that, potentially +requiring further changes. (Previously, the function declaration was +treated as not having a prototype.) + +

Incorrect uses of the return statement (-Werror=return-mismatch)

+ +GCC no longer accepts return statements with expressions +in functions which are declared to return void, or +return statements without expressions for functions +returning a non-void type. + +

+To address this, remove the incorrect expression (or turn it into a +statement expression immediately prior to the return +statements if the expression has side effects), or add a dummy return +value, as appropriate. If there is no suitable dummy return value, +further changes may be needed to implement appropriate error handling. + +

+Previously, these mismatches were diagnosed as +a -Wreturn-type warning. This warning still exists, and +is not treated as an error by default. It now covers remaining +potential correctness issues, such as reaching the closing +brace } of function that does not +return void. + +

+By default, GCC still accepts returning an expression of +type void from within a function that itself +returns void, as a GNU extension that matches +standard C++ rules in this area. + +

Using pointers as integers and vice versa (-Werror=int-conversion)

+ +GCC no longer treats integer types and pointer types as equivalent in +assignments (including implied assignments of function arguments and +return values), and instead fails the compilation with a type error. + +

+It makes sense to address missing int types, implicit +function declarations, and incorrect return statement +usage prior to tackling these int-conversion issues. +Some of them will be caused by missing types treated +as int, and the default int return type of +implicitly declared functions. + +

To fix the remaining int-conversions issues, add casts +to an appropriate pointer or integer type. On GNU systems, the +standard types +intptr_t and uintptr_t (defined +in <stdint.h>) are always large enough to store all +pointer values. If you need a generic pointer type, consider +using void *. + +

In some cases, it may be more appropriate to pass the +address of an integer variable instead of a cast of the variable's +value. + +

Type checking on pointer types (-Werror=incompatible-pointer-types)

+ +GCC no longer allows implicitly casting all pointer types to all other +pointer types. This behavior is now restricted to the void * +type and its qualified variations. + +

+To fix compilation errors resulting from that, you can add the +appropriate casts, and maybe consider using void * +in more places (particularly for old programs that predate the +introduction of void * into the C language). + +

+Programs that do not carefully track pointer types are likely to +contain aliasing violations, so consider building +with -fno-strict-aliasing. (Whether casts +are written manually or performed by GCC automatically does not make a +difference in terms of strict aliasing violations.) + +

+A frequent source of incompatible function pointer types involves +callback functions that have more specific argument types (or less +specific return types) than the function pointer they are assigned to. +For example, old code which attempts to sort an array of strings might +look like this: + +

+#include <stddef.h>
+#include <stdlib.h>
+#include <string.h>
+
+int
+compare (char **a, char **b)
+{
+  return strcmp (*a, *b);
+}
+
+void
+sort (char **array, size_t length)
+{
+  qsort (array, length, sizeof (*array), compare);
+}
+
+ +To address this, the callback function should be defined with the +correct type, and the arguments should be cast as appropriate before +they are used (as calling a function through a function pointer of an +incorrect type is undefined): + +
+int
+compare (const void *a1, const void *b1)
+{
+  char *const *a = a1;
+  char *const *b = b1;
+  return strcmp (*a, *b);
+}
+
+ +

+A similar issue can arise with object pointer types. Consider a +function that is declared with an argument of type +void **, and you want to pass the address of a variable +of type int *: + +

+extern int *pointer;
+extern void operate (int command, void **);
+
+operate (0, &pointer);
+
+ +In these cases, it may be appropriate to make a copy of the pointer +with the correct void * type: + +
+extern int *pointer;
+extern void operate (int command, void **);
+
+void *pointer1 = pointer;
+operate (0, &pointer1);
+pointer = pointer1;
+
+ +As mentioned initially, adding the cast here would not eliminate any +strict aliasing violation in the implementation of +the operate function. Of course in general, introducing +such additional copies may alter program behavior. + +

+Some programming styles rely on implicit casts between related object +pointer types to implement C++-style struct inheritance. +It may be possible to avoid writing manual casts with +the -fplan9-extensions option and unnamed +initial struct fields for the base type in +derived structs. + +

+Some programs use a concrete function pointer type such as +void (*) (void) as a generic function pointer type +(similar to void * for object pointer types), and rely on +implicit casts to and from this type. The reason for that is that C +does not offer a generic function pointer type, and standard C +disallows casts between function pointer types and object pointer +types. On most targets, GCC supports implicit conversion +between void * and function pointer types. However, for +a portable solution, the concrete function pointer type needs to be +used, together with explicit casts. + +

Impact on Autoconf and build environment probing in general

+ +Most Autoconf +probes that check for build system features are written in such a way +that they trigger a compiler error if a feature is missing. The new +errors may cause GCC to fail compiling a probe when it worked before, +unrelated to the actual objective of the probe. These failed probes +tend to disable program features together with their tests, +resulting in silently dropping features. + +

+In cases where this is a concern, generated config.log, +config.h and other source code files can be compared +using diff, to ensure there are no unexpected +differences. + +

+This phenomenon also impacts similar procedures that are part of CMake, Meson, +and various build tools for C extension modules of scripting +languages. + +

+Autoconf has supported C99 compilers since at least version 2.69 in +its generic, core probes. (Specific functionality probes may have +issues addressed in more recent versions.) Versions before 2.69 may +have generic probes (for example for standard C support) that rely on +C features that were removed in C99 and thus fail with GCC 14. + +

Turning errors back into warnings

+ +

+Sources that cannot be ported to standard C can be compiled +with -fpermissive, -std=gnu89, +or -std=c89. Despite their names, the latter two options +turn on support for pre-standard C constructs, too. With the +-fpermissive option, programs can use C99 inlining +semantics and features that were removed from C99. Alternatively, +individual errors can be downgraded to warnings using +the relevant -Wno-error=… option, or disabled completely +with -Wno-…. For example, +-Wno-error=incompatible-pointer-types turns off most type +checking for pointer assignments. + +

+Some build systems do not pass the CFLAGS variable to all +parts of the builds, and may require setting CC to +something like gcc -fpermissive instead. If the build +system does not support whitespace in the CC variable, a +wrapper script like this may be required: + +

+#!/bin/sh
+exec /usr/bin/gcc -fpermissive "$@"
+
+ +

Accommodating C code generators

+ +C code generators that cannot be updated to generate valid standard C +can emit +#pragma GCC diagnostic warning +directives to turn these errors back into warnings: + +
+#if defined __GNUC__ && __GNUC__ >= 14
+#pragma GCC diagnostic warning "-Wimplicit-function-declaration"
+#pragma GCC diagnostic warning "-Wincompatible-pointer-types"
+#pragma GCC diagnostic warning "-Wint-conversion"
+#pragma GCC diagnostic warning "-Wreturn-mismatch"
+#endif
+
+ +Not included here are -Wimplicit-int +and -Wdeclaration-missing-parameter-type because they +should be straightforward to address in a code generator. + +

Future directions

+ +This section concerns potential future changes related to language +features from the C standard and other backwards compatibility +hazards. These plans may change and are mentioned here only to give +guidance which source-level changes to prioritize for future +compatibility. + +

+It is unclear at which point GCC can enable the C23 bool +keyword by default (making the bool type available +without including #include <stdbool.h>). +Many programs define their own bool types, sometimes with +a different size than the built-in _Bool type. A +further complication is that even if the sizes are the same, a custom +bool typically does not have trap representations, +while _Bool and the new bool type do. This +means that there can be subtle compatibility issues, particularly when +processing untrusted, not necessarily well-formed input data. + +

+GCC is unlikely to warn about function declarations that are not +prototypes by default. This means that there is no stringent reason +to turn + +

+void do_something ();
+
+ +into + +
+void do_something (void);
+
+ +except for diagnosing extraneous ignored arguments as errors. A +future version of GCC will likely warn about calls to functions +without a prototype which specify such extraneous arguments +(do_something (1), for example). Eventually, GCC will +diagnose such calls as errors because they are constraint violations +in C23. + +

+GCC will probably continue to support old-style function definitions +even once C23 is used as the default language dialect. +

C++ language issues

Header dependency changes

----------------------------------------------------------------------- Summary of changes: htdocs/gcc-14/porting_to.html | 466 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 466 insertions(+) hooks/post-receive -- gcc-wwwdocs