Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C preprocessing fails to stop immediately after an #error

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.

like image 936
Zheyuan Li Avatar asked Apr 06 '16 23:04

Zheyuan Li


People also ask

What is preprocessor error in C?

#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.

Which can generate preprocessor error?

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.

What is the use of #error in C?

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.

What is the purpose of the pre processor directive error?

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.


1 Answers

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.

like image 51
templatetypedef Avatar answered Oct 07 '22 11:10

templatetypedef