Problem
Today in the learning process communication-signal Signal–linux kernel anatomy (ix)
Met with a strange question
of ‘oldact’ isn’t known
So Fq to Google.
Analysis for a long time, finally found the cause of the problem. and write it down.
Found
The code for the test is as follows
#include <stdio.h>#include <stdlib.h>#include <signal.h>#include <bits/sigaction.h>int main(){ struct sigaction act; return0;}
- gcc test.cCompile by default with no errors
- gcc test.c -std=gnu99andgcc test.c -std=gnu9xError-free
Cause resolution
See Sigaction () and ANSI C
======
Because Sigaction is a POSIX system call.
Maybe so, but it's isn ' t part of Ansi-c
Generally, you need-isolate system dependencies in as few places as possible, so that's most of the Your code can be compiled With-ansi
If You dance barefoot on the broken glass of undefined behaviour, you ' ve got to expect the occasional cut.
If at first you don ' t succeed, try writing your phone number on the exam paper.
======
Am I Right in thinking then That-ansi sets something this makes the preprocessor ignore the non ANSI standard parts of SI Gnal.h?
Yes.
Things which is not in ansi-c get excluded when you specify-ansi, simply because they ' re not guaranteed to be everywhere Else. Regard-ansi as a strict portability checker.
Because it is required to run on several different flavours of UNIX.
Perhaps you should relax the test a little bit and down to POSIX compatibility. That's should allow you to port your code easily to most unices (plural of Unix), and still use sigaction () since it's part of POSIX.
If you can ' t manage ANSI, at least POSIX are a good 2nd choice to go for.
If you have the many source files, you should is able to arrange for nearly all of the them to be compiled With-ansi, and just a Few which rely on POSIX. That's the, any porting surprises-do has the'll being localised in just a few places.
If You dance barefoot on the broken glass of undefined behaviour, you ' ve got to expect the occasional cut.
If at first you don ' t succeed, try writing your phone number on the exam paper.
-std=c99 problem with signal.h
Actually if you want strict ANSI/C99 compliance, you should use "signal" instead of "sigaction" which are defined by POSIX. 1-2001.
In fact Posix.1 supports both but prefers "sigaction", whereas ANSI/C99 supports only "signal".
Of course, "signal" is very much system dependent.
See "Mans Signal", "Man sigaction".
The following link has a lot of information.
Https://www.securecoding.cert.org/confluence/display/seccode/SIG00-C.+Mask+signals+handled+by+noninterruptible +signal+handlers
In fact, it is very clear, that is, signal is a ANSI/C99 compiler support functions, Sigaction is later in the posix.1-2001 new interface, then because of the forward-compatible features, ANSI/C99 does not support the Sigaction function interface.
In other words, most operating systems support signal, but only partially support sigaction.
So when the compiler is processing, if you specify –ansi or-STD=C99 instructions, the compiler will think that if you compile a standard C program, then at compile time (exactly the preprocessing phase) you do not conform to the C standard of the place to discard,
How do you abandon it? Of course it's through the macro.
Verify
We know that the GCC compiler can preprocess with-e to generate preprocessed files.
So now we're going to verify all of a sudden, we are in the generated preprocessing file, searching for the specified sigaction keyword, looking at the preprocessed file, there is no definition of the struct body
gcc -E test.c -std=c99 | grep sigactiongcc -E test.c --ansi | grep sigaction
Obviously, after we have specified a compiler that uses the C standard, the compiler masks out the interfaces for non-C standards in the preprocessing phase.
We also use the GNU compiler Extension's C compiler for preprocessing to see what
gcc -E test.c -std=gnu99 | grep sigactiongcc -E test.c -std=gnu9x | grep sigaction
Well, we're not very clear now.
For details on the specific GCC compilation parameters, see GCC command-line Options
We can see that –ansi specifies compiling using the old standard Ansic standard,-std=c99 specifying the new C99 standard compilation, and thegnu99gnu9xGCC compiler's own implementation of the C99 standard
What are these relationships?
First the standard committee specifies the language standard, which is ANSI and later C88,C99 standard
But only the standard how to do, there must be a compiler to support ah, so each compiler began to gradually support the new standards, but also the emergence of-std=c89,-stdc99, in order to be compatible with the previous program, while retaining the old standard –ansi
However, the support of the standard, can not be all of a sudden, only to achieve a part, and slowly expand, in addition, because some of the standards may not be practical, may need some extension, so there is a-std=gnu99, and now a lot of compilers of C syntax have some different extensions, Some of these extensions have been added to the new standards, some of which have not been added or are being moved.
Workaround 1
is the type of compiler that we compile, such as-std=gnu99
Workaround 2
To#include <signal.h>explicitly add sigaction header files after
#include <bits/sigaction.h>
This allows the compiler to explicitly compile the sigaction definition
However, in this case it is important to note that#include <bits/sigaction.h>#include <signal.h>after
Becausesignalit will be#errorpreprocessed to check that ' bits/sigaction.h is included,
If the user does not include it, the preprocessing phase will error
#error "Never include <bits/sigaction.h> directly; use <signal.h> instead."
Error storage size of ' act ' isn ' t known when using STD=C99 to compile the struct sigaction