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

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

Related

compile C code with no flag other than -o

Im doing an assignment and the requirement instruction say "Your code should compile correctly (no warnings and errors) with no flags other -o. you should compile your code to a debug-able executable without producing any warnings or error messages. (Note that -O and -o are different flags.)"
So Im so confused what does the " no flags other -o " means. As far as I know, "flag is a general tool for rudimentary signalling and identification, especially in environments where communication is similarly challenging.", so does the requirement mean that we can't use any for loop ?
No, the requirement is referring to command-line flags, ie options to the compiler. Eg, assuming gcc, gcc -o foo foo.c.
However, since the program is meant to be debuggable, the requirements are contradictory because creating a debuggable executable requires (for gcc) the -g flag.
On many compilers, you can control the warning level with flags. The requirement here is to not use those flags, yet raise no warning.
Said differently, you are just asked to write neat and clean C code using no specific extension nor any semi valid constructs (code not conforming to the standard but accepted with warnings by a compiler)

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.

pthread_cleanup_push and O2 CFLAGS

I have some warning when compiling a piece of code using pthread_cleanup_push/pop with -O2 CFLAGS. Just by removing the O2 cflags in the Makefile make it compile without issue.
Is it forbidden to use gcc optimization with these pthread macros ? I was not able to find anything in man or documentation. By the way, is there any alternative to clean stuff at the end of a thread ? Also it is working perfectly with gcc arm. But not on x86 gcc.
Warning :
x/x.c:1292:2: warning: variable ‘__cancel_routine’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Wclobbered]
pthread_cleanup_push(x_cleanup, &fd);
My current CFLAGS option :
-W -Wall -Wformat -Wformat-security -Wextra -Wno-unused-result,
-Wextra -Wno-long-long -Wno-variadic-macros -Wno-missing-field-initializers
-std=gnu99 -O2
This issue has been reported several times now in GCC tracker (see here). I believe that this warns about real issue in pthread.h (see my comment). __cancel_routine is not marked as volatile so it's value is indeed undefined after return via longjmp which may cause arbitrary consequences.
The only solution is to remove the Werror until a fix ?
I'd rather go with -Wno-clobbered, to keep other warnings enabled.
Roll back on a previous version of gcc on x86 ?
You'll have to rollback to pre-2014 times which is quite a change... I think that if the code works for you, just disable -Wclobbered (with a descriptive comment).
But I did want to be sure that its was not a bigger issue which can cause unexpected behavior of my code or bugs.
Glibc code looks really suspicious. I'd wait for comments from GCC devs and if there is none, report this to Glibc developers.

C make file -Wno-unused-parameter flag

I am trying to compile some C code in Linux Kernel.
I have a huge project that compiles without any warnings. The compilation line is very very long and complex.
In project, the compiler did not warn about variables that are part of the function signature that were not used (even though it contains flags such as -Wall). such as:
void foo (int a) {
}
I cannot see why it would not warn on it.
So i checked the actual compilation lines on the original project by running:
make -n
It does not have the flag -Wno-unused-parameter that cancels this warning.
Does anyone know of a flag that cancels this warning? Maybe a different flag that contains the -Wno-unused-parameter flag ?
Thanks
Matt
According to Warning Options - Using the GNU Compiler Collection (GCC), -Wall doesn't enable -Wunused-parameter, so this warning isn't mysteriously cancelled, but simply not enabled.

How does GCC behave if passed conflicting compiler flags?

I know that if you execute GCC as such:
gcc -O3 -O2 foo.c
GCC will use the last optimization flag passed (in this case O2). However, is this true for all flags? For example, if I execute GCC like so:
gcc -mno-sse -msse bar.c
Will it support SSE since that was the last flag passed, or would this result in undefined behavior? My initial experimentation seems to indicate that it will support SSE, but I'm not sure if this is true for all cases.
Normally later options on the line override ones passed previously, as you mention in your first example. I haven't personally come across any different behaviour for -m or -f flags, but I don't know of a specific reference in the documentation.
Note that some options don't behave this way:
$ gcc example.c -DABC -DABC=12
<command-line>: warning: "ABC" redefined
<command-line>: warning: this is the location of the previous definition
So there would need to be a -UABC in between there to shut that warning up.
As an aside, clang is particularly good at solving this problem - it will produce a warning if it ignores a command line option, which can help you out.

Resources