How does GCC behave if passed conflicting compiler flags? - c

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.

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.

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.

Optimization setting

In c we can enble the optimization setting by enabling the flag -O for enable all the possible optimization and -O0 will disable all enabled optimization.
My question is that this flags are message to whom?means to compiler or kernel?
All command line arguments you supply are interpreted by the compiler (or compiler driver, in the case of some compilers like gcc). They may then be passed on to other programs that the compiler (or compiler driver) executes to complete particular tasks.
Incidentally, -o is not an optimisation setting with quite a few compilers. It usually specifies the name of an output file. For example, gcc -c file.c -o anotherfile.o compilers file.c and produces an object file named anotherfile.o.
The optimisation setting is usually -O (for example -O3). Note the uppercase O. It won't necessarily be passed to every program executed by the compiler/driver. For example, gcc -O3 file.c -o program compiles file.c with optimisation setting -O3 and produces an output executable named program. To do that, the linker is invoked, as well as various compilation phases (preprocessor, compiler proper, etc). -O3 will not normally be passed to the linker - it is a compilation option which linkers normally do not understand.
The O flags are passed to the compiler, not the kernel. The kernel has nothing to do with compilation. These flags determine how aggressively the optimizer will do it's job. A practical example would be clang -O3 WannabeObjectFile.c.
Edit: I made a mistake, the lower case o flag is used to specify the output file. The uppercase O is used to specify optimization level.

Calling multiple std=cXX in C makefile

I was wondering what happens if you call multiple std=cXX? I tried it in my code and nothing outward happened on compile so I didnt know if it worked or not.
-std=c99 -std=c11 -std=c1x
What happens? Does it use all 3 std or is the last one that called?
Most gcc flags follow a model that the last conflicting option on the line is the one that is actually in force. For example, using -O -O1 -O2 -O3 really means the same as -O3.

Compiling C code using zmq API

I am failed to compile builtin example hwserver.c using ZeroMQ APIs. I have tried every possible way.
gcc -lzmq hwserver.c -o hwserver
It prompts me with:
hwclient.c:(.text+0x22): undefined reference to `zmq_ctx_new'
hwclient.c:(.text+0x3a): undefined reference to `zmq_socket'
hwclient.c:(.text+0x52): undefined reference to `zmq_connect'
hwclient.c:(.text+0x94): undefined reference to `zmq_send'
hwclient.c:(.text+0xb8): undefined reference to `zmq_recv'
hwclient.c:(.text+0xe4): undefined reference to `zmq_close'
hwclient.c:(.text+0xf0): undefined reference to `zmq_ctx_destroy'
collect2: error: ld returned 1 exit status
I'm using zeromq-3.2.2 on ubuntu-12.10
Any help really appreciated.
Thanks,
-Sam
Order of arguments to gcc does matter a lot.
Try
gcc -Wall -g hwserver.c -lzmq -o hwserver
You need first the warning and optimizations or debugging flags (e.g. -Wall for all warnings, -g for debugging information), then the optional preprocessor flags (like -D or -I but you have none of them), then the source files, and at last the libraries -lzmq (order is relevant: from high level libraries to low level ones) and the output option -o hwserver (which could be elsewhere).
Read the gcc documentation, notably the chapter about invoking GCC.
Don't forget the -Wall : you really want to get all warnings, and you should improve your code till no warnings are given. You could even want -Wextra to get more extra warnings.
Don't forget the debugging information flag -g: you will need to use the gdb debugger to debug your program.
Later, use -O or -O2 to optimize the binary program (the compiler will then produce more efficient, but less debuggable, machine code). Care about that only when your program is debugged.
As soon as you want to develop real-sized C programs (i.e. your project made of several source files and some header file[s]), you'll need a builder infrastructure, like GNU make (a very common builder; you could try omake instead).
See also this answer to a related question.
try again
gcc hwserver.c -o hwserver -lzmq
Your order of the parameters is incorrect.

Resources