GCC options for strictest C code? [duplicate] - c

This question already has answers here:
Recommended GCC warning options for C [closed]
(15 answers)
Closed 8 years ago.
What GCC options should be set to have GCC as strict as possible? (and I do mean as strict as possible) I'm writing in C89 and want my code to be ANSI/ISO compliant.

I'd recommend using:
-Wall -Wextra -std=c89 -pedantic -Wmissing-prototypes -Wstrict-prototypes \
-Wold-style-definition
You should compile with -O as well as -g as some warnings are only available when the optimizer is used (actually, I usually use -O3 for spotting the problems). You might prefer -std=gnu89 as that disables fewer extensions in the libraries. OTOH, if you're coding to strict ANSI C89, maybe you want them disabled. The -ansi option is equivalent to -std=c89 but not quite as explicit or flexible.
The missing prototypes warns you about functions which are used (or external functions defined) without a prototype in scope. The strict prototypes means you can't use 'empty parentheses' for function declarations or definitions (or function pointers); you either need (void) or the correct argument list. The old style definition spots K&R style function definitions, such as:
int old_style(a, b) int a; double b; { ... }
If you're lucky, you won't need to worry about that. I'm not so lucky at work, and I can't use strict prototypes, much to my chagrin, because there are too many sloppy function pointers around.
See also: What is the best command-line tool to clean up code

This set of options is pretty good:
-Wall -Wextra -ansi -pedantic
You'll have to read the documentation to see if there are any extra warnings getting left out by that combination.
You should be warned that strict C89 doesn't include support for // style comments, and there are some pretty serious restrictions on the number of significant characters in the names of objects with external linkage.

Related

What is making my compiler compile the code despite references to undeclared functions (in headers or otherwise)?

A function, before being used, needs to be declared either in a included header or otherwise (though not a good practice). The header file describes the functions and variables that may be found in a library or an object file and the compiler can create (as of yet) unreferenced symbols to be resolved later whilst linking.
However, my compiler (gcc based toolchain called esp-open-sdk (xtensa CPU)) continues despite finding no reference to a function in the headers and only in the linking stage does the linker intimate of an `undefined reference to <-function-name->'.
Another strange behaviour is that the compiler says nothing if there is no return statement, and the function is not "void".
My question is: What is causing this behaviour? I think it's unlikely but is it some compiler flag?
My compiler flags are:
CFLAGS = -Os -g -O2 -Wpointer-arith -Wundef -Werror -Wl,-EL -fno-inline-functions -nostdlib -mlongcalls -mtext-section-literals -D__ets__ -DICACHE_FLASH
and the linker flags are:
LDFLAGS = -nostdlib -Wl,--no-check-sections -u call_user_start -Wl,-static
Probably you use an old version of gcc. Before version 5.x, gcc defaults to a non-standard called "gnu90", which is a non-standard version of the obsolete C90 standard. There is no reason to ever use gnu90 unless you are maintaining some old Linux code. To avoid this, compile with:
-std=c11 -pedantic-errors
-std=c11 meaning you want the compiler to use the current C standard, without involving gnus or other strange animals. -pedantic-errors means that you want it to actually follow the standard and not just pretend to do it.
In order to get the warning for no return from functions, you need to use the option -Wreturn-type, which is included by using -Wall. Always compile with
-Wall -Wextra
Note that "Wall" does not stand for "all warnings", as it leads you to believe. Rather, -Wall means a fistful of warnings and -Wextra means a few warnings more.

What GCC parameters do I need in addition to -std and -pedantic-errors for portability? [duplicate]

This question already has answers here:
What is the purpose of using -pedantic in the GCC/G++ compiler?
(8 answers)
Do I need -pedantic flag from GCC with C11?
(6 answers)
How to enable c11 on later versions of gcc?
(4 answers)
M_PI not available with gcc --std=c11 but with --std=gnu11?
(3 answers)
What is the default C -std standard version for the current GCC (especially on Ubuntu)?
(7 answers)
Closed 5 years ago.
So I used to think using -std=c11 and -pedantic-errors were enough to force gcc to only compile code that would also compile on other standard-compliant compilers (possibly on other platforms, assuming no platform-specific libraries are used), such as other versions of gcc or other compilers entirely.
However apparently compiling under mingw on Windows 7 with both -pedantic-errors -std=c11 allows code to compile that contains this:
struct foo {
//(some members)
};
struct bar {
struct foo; //note the lack of a member name
//(other members)
};
Which causes the same code, also using gcc with both -pedantic-errors -std=c11 to fail under Ubuntu with error: declaration does not declare anything
If anonymous members like aren't allowed in ISO-C11, then why did gcc let that code pass in the first place? What am I missing about what -pedantic-errors -std=c11 actually does? What other parameters (if any) do I need to ensure gcc only compiles code that is standard-compliant enough to work under other versions of gcc, on other platforms, and/or other compilers given those compilers are themselves standard-compliant? I.e. make it consistent across platforms.
I am not asking what the purpose of -pedantic-errors is, but what parameter(s) can force gcc to only compile code that will compile everywhere (i.e. no gcc-specific extensions or non-standard stuff that doesn't always work). So -pedantic-errors but even more strict, as -pedantic-errors still allows extensions, it only forbids ones explicity forbidden in the standard.

How to disable GNU C extensions?

As you can see in the following code, I've introduced a nested function within main():
#include <stdio.h>
int main(){
int a=5;
printf("%d\n",a);
{
int a=10;
printf("%d\n",a);
}
printf("%d\n",a);
//Nested function
int main(int a){
if(a>0)printf("%d\n",a--);
return 0;
}
main(7);
return 0;
}
As far as I could understand I used the -std=c99 flag in gcc to "disable" the unnecessary extensions, but I did not get any error.
gcc temp3.c -std=c99 -o temp3.out
Where have I made the mistake?
Add -pedantic and -Werror to the command line.
Using GCC 6.1.0 on Mac OS X 10.11.6, with your original code in a file ped73.c and my default compilation options, I get:
$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes \
> -Wold-style-definition ped73.c -o ped73
ped73.c:3:5: error: function declaration isn’t a prototype [-Werror=strict-prototypes]
int main(){
^~~~
ped73.c: In function ‘main’:
ped73.c:3:5: error: old-style function definition [-Werror=old-style-definition]
ped73.c:13:6: error: ‘main’ takes only zero or two arguments [-Werror=main]
int main(int a){
^~~~
ped73.c:13:6: error: ‘main’ is normally a non-static function [-Werror=main]
$
Renaming the nested function to nested and using int main(void), I get:
$ gcc -O3 -g-std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes
> -Wold-style-definition -o ped73
$
Using the extra option -pedantic I get:
$ gcc -O3 -g -std=c11 -Wall -Wextra -Werror -Wmissing-prototypes -Wstrict-prototypes \
> -Wold-style-definition -pedantic ped73.c -o ped73
ped73.c: In function ‘main’:
ped73.c:13:2: error: ISO C forbids nested functions [-Werror=pedantic]
int nested(int a){
^~~
cc1: all warnings being treated as errors
$
Then what's the point of -std=c99?
The -std=c99 flag disables the GNU extensions that GCC thinks should be disabled — such as POSIX versions, etc. See C Dialect Options for the meaning of -std=; see Warning Options for the meaning of -pedantic.
-Wpedantic
-pedantic
Issue all the warnings demanded by strict ISO C and ISO C++; reject all programs that use forbidden extensions, and some other programs that do not follow ISO C and ISO C++. For ISO C, follows the version of the ISO C standard specified by any -std option used.
Valid ISO C and ISO C++ programs should compile properly with or without this option (though a rare few require -ansi or a -std option specifying the required version of ISO C). However, without this option, certain GNU extensions and traditional C and C++ features are supported as well. With this option, they are rejected.
-Wpedantic does not cause warning messages for use of the alternate keywords whose names begin and end with __. Pedantic warnings are also disabled in the expression that follows __extension__. However, only system header files should use these escape routes; application programs should avoid them. See Alternate Keywords.
Some users try to use -Wpedantic to check programs for strict ISO C conformance. They soon find that it does not do quite what they want: it finds some non-ISO practices, but not all—only those for which ISO C requires a diagnostic, and some others for which diagnostics have been added.
A feature to report any failure to conform to ISO C might be useful in some instances, but would require considerable additional work and would be quite different from -Wpedantic. We don't have plans to support such a feature in the near future.
Where the standard specified with -std represents a GNU extended dialect of C, such as ‘gnu90’ or ‘gnu99’, there is a corresponding base standard, the version of ISO C on which the GNU extended dialect is based. Warnings from -Wpedantic are given where they are required by the base standard. (It does not make sense for such warnings to be given only for features not in the specified GNU C dialect, since by definition the GNU dialects of C include all features the compiler supports with the given option, and there would be nothing to warn about.)
And there's also a different option that gives pedantic errors:
-pedantic-errors
Give an error whenever the base standard (see -Wpedantic) requires a diagnostic, in some cases where there is undefined behavior at compile-time and in some other cases that do not prevent compilation of programs that are valid according to the standard. This is not equivalent to -Werror=pedantic, since there are errors enabled by this option and not enabled by the latter and vice versa.
There are multiple questions about which GCC compiler options to use, including:
Recommended gcc warning options for C
What is the purpos of using -pedantic in GCC/G++ compiler
warning: implicit declaration of function when compiling C source
and no doubt there are many others that could be added to that list. Basically, the default options I use ensure that functions are declared before they are used (or, are defined as a static function before they are used), and that the function declarations have full prototypes — no empty parentheses () — and use the -Wall and -Wextra to spot a number of other routine problems, including mismatches between format strings and arguments to the printf() and scanf() families of functions.

How to compile a Linux kernel module using -std=gnu99?

I've recently learned how to program simple character drivers and while playing around with the code I noticed that I get a lot of the following GCC warnings thrown for my C99 code:
warning: ISO C90 forbids mixed declarations and code
I assume this is because the main Linux kernel Makefile is set to compile using a non-C99 standard. I searched around I found this answer here on stackoverflow: How to use make and compile as C99?
So I naturally tried the following in my Makefile:
ccflags-y := -std=gnu99
Unfortunately this didn't silence the GCC warnings. I checked the verbose output of make and verified that GCC is indeed executed with the -std=gnu99 tacked on at the end; so I'm a bit confused.
How do I properly compile a Linux kernel module using the -std=gnu99 option?
EDIT:
I noticed the GCC output shows this option: -Wdeclaration-after-statement. Is this why I am getting the warnings even with the -std=gnu99 option?
It turns out that -std=gnu99 does in fact work; I began seeing errors regarding C99 features after removing the compiler flag. So that meant something else was causing the warnings to print out besides the -std= option.
After parsing through the verbose output via make V=1, I discovered the -Wdeclaration-after-statement option as part of the GCC execution. This was the cause of the ISO C90 mixed declaration warnings I saw.
To disable the ISO C90 warnings, pass this to GCC: -Wno-declaration-after-statement.
For example:
ccflags-y := -std=gnu99 -Wno-declaration-after-statement
You can also specify the flag in your Makefile, if you have one:
FLAGS=-std=gnu99

GCC options to enforce Ansi C standard check?

What gcc options shall I use to enforce ANSI C (C99) warnings/errors?
gcc (GCC) 3.4.2 (mingw-special)
I'm using:
gcc -pedantic -ansi -std=c99
is this correct?
The -ansi flag is synonymous with the -std=c89 flag.
Just using -std=c99 with -pedantic should be sufficient.
When in doubt, you can always refer to the GCC documentation. As of GCC 3.4.2, the chapter to read is 2 - Language Standards Supported by GCC.
This is an old question but I just wanted to add some extra points.
Firstly, regardless of the set of generic command-line switches you supply to GCC, currently it doesn't appear to be possible to make GCC to report all constraint violations as "errors" and everything else as "warnings". Some of the diagnostic messages GCC reports as "warnings" are in fact constraint violations (i.e. "errors") from the point of view of C language, but there's no way to force GCC to recognize that fact and generate an "error" diagnostic. Quite possibly that a more precise separation can be achieved by fine-tuning individual warning types, but I'm not sure GCC settings provide sufficient granularity to achieve a good match.
Secondly, GCC provides -pedantic-errors option that can be used in place of plain -pedantic, which is intended to enable a more precise (as described above) classification of diagnostic messages into "errors" and "warnings". It is still not perfect though.
P.S. The language specification doesn't require/define the separation of diagnostic messages into "errors" and "warnings", but in practice many programmers expect constraint violations to be reported as "errors". I thought that you might have meant something like that when you mentioned "enforcing warnings/errors" in your question.
-ansi
In C mode, this is equivalent to -std=c89. In C++ mode, it is equivalent to -std=c++98.
ANSI C isn't the same as C99 (yet). Also, -Wall might also be of interest, but only -pedantic should do what you want.

Resources