My question today should not be very much complicated, but I simply can't find a reason/solution. As a small, reproducible example, consider the following toy C code
#define _state_ 0
#if _state_ == 1
int foo(void) {return 1;}
#else
/* check GCC flags first
note that -mfma will automatically turn on -mavx, as shown by [gcc -mfma -dM -E - < /dev/null | egrep "SSE|AVX|FMA"]
so it is sufficient to check for -mfma only */
#ifndef __FMA__
#error "Please turn on GCC flag: -mfma"
#endif
#include <immintrin.h> /* All OK, compile C code */
void foo (double *A, double *B) {
__m256d A1_vec = _mm256_load_pd(A);
__m256d B_vec = _mm256_broadcast_sd(B);
__m256d C1_vec = A1_vec * B_vec;
}
#endif
I am going to compile this test.c
file by
gcc -fpic -O2 -c test.c
Note I did not turn on GCC flag -mfma
, so the #error
will be triggered. What I would expect, is that compilation will stop immediately after GCC sees this #error
, but this is what I got with GCC 5.3:
test.c:14:2: error: #error "Please turn on GCC flag: -mfma"
#error "Please turn on GCC flag: -mfma"
^
test.c: In function ‘foo’:
test.c:22:11: warning: AVX vector return without AVX enabled changes the ABI [-Wpsabi]
__m256d A1_vec = _mm256_load_pd(A);
^
GCC does stops, but why does it also pick up a line after #error
? Any explanation? Thanks.
For people who want to try, there are some hardware requirement. You need an x86-64 with AVX
and FMA
instruction sets.
#error is a preprocessor directive in C which is used to raise an error during compilation and terminate the process. Syntax: #error <error message> C. Usually, the error message is associated with preprocessor conditional statements like #if, #ifdef and others.
The directive ' #error ' causes the preprocessor to report a fatal error. The tokens forming the rest of the line following ' #error ' are used as the error message. The directive ' #warning ' is like ' #error ', but causes the preprocessor to issue a warning and continue preprocessing.
In the C Programming Language, the #error directive causes preprocessing to stop at the location where the directive is encountered. Information following the #error directive is output as a message prior to stopping preprocessing.
A preprocessor error directive causes the preprocessor to generate an error message and causes the compilation to fail. The #error directive is often used in the #else portion of a #if – #elif – #else construct, as a safety check during compilation.
I have a draft copy of the C ISO spec, and in §4/4 - it states
The implementation shall not successfully translate a preprocessing translation unit containing a #error preprocessing directive unless it is part of a group skipped by conditional inclusion.
Later on, in §6.10.5, where #error
is formally defined, it says
A preprocessing directive of the form
# error pp-tokens opt new-line
causes the implementation to produce a diagnostic message that includes the specified sequence of preprocessing tokens.
In other words, the spec only requires that any code that has an #error
just needs to fail to compile and report an error message along the way, not that the compilation immediately needs to terminate as soon as #error
is reached.
Given that it's considered good practice to always check the top-level errors reported by a compiler before later ones, I'd imagine a competent programmer who saw a string of errors beginning with an #error
directive would likely know what was going on.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With