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
+ 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. + ++ +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. + +
int
types (-Werror=implicit-int
)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)); + } ++ +
-Werror=implicit-function-declaration
)
+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. + +
-Werror=declaration-missing-parameter-type
)-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.) + +
return
statement (-Werror=return-mismatch
)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.
+
+
-Werror=int-conversion
)
+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. + +
-Werror=incompatible-pointer-types
)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 struct
s.
+
+
+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.
+
+
+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. + +
+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 "$@" ++ +
#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.
+
+
+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. +