在#error之后,C预处理无法立即停止

李哲源*_*李哲源 6 c gcc compilation avx c-preprocessor

我今天的问题应该不是很复杂,但我找不到理由/解决方案.作为一个小型,可重复的示例,请考虑以下玩具C代码

#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
Run Code Online (Sandbox Code Playgroud)

我要编译这个test.c文件

gcc -fpic -O2 -c test.c
Run Code Online (Sandbox Code Playgroud)

注意我没有打开GCC标志-mfma,因此#error将触发.我所期待的是,在GCC看到之后编译将立即停止#error,但这是我在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);
           ^
Run Code Online (Sandbox Code Playgroud)

海湾合作委员会确实停止了,但为什么它之后也会收到一条线#error?任何解释?谢谢.


对于想要尝试的人,有一些硬件要求.你需要一个x86-64 AVX FMA指令集.

tem*_*def 5

我有一份C ISO规范的草稿副本,在§4/ 4中 - 它说明了

实现不应成功转换包含#error预处理指令的预处理转换单元,除非它是由条件包含跳过的组的一部分.

后来,在§6.10.5中,#error正式定义了它,它说

表单的预处理指令 # error pp-tokens opt new-line 使实现生成包含指定序列的预处理标记的诊断消息.

换句话说,规范只要求任何代码#error只需要编译并报告错误消息,而不是编译立即需要立即终止#error.

鉴于始终检查编译器在之后的报告之前报告的顶级错误被认为是一种好的做法,我想象一个有能力的程序员看到以#error指令开头的一系列错误可能会知道发生了什么.

  • 这是一个实现质量的问题...如果编译器响应任何错误并且"你的程序坏了"这个消息也会符合要求 (2认同)