【问题标题】:C preprocessing fails to stop immediately after an #error#error 后 C 预处理无法立即停止
【发布时间】:2016-07-27 14:43:14
【问题描述】:

我今天的问题应该不是很复杂,但我根本找不到原因/解决方案。作为一个可重现的小例子,请考虑以下玩具 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

我将编译这个test.c文件

gcc -fpic -O2 -c test.c

注意我没有打开 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);
           ^

GCC 确实停止了,但为什么它还在#error 之后接了一行?有什么解释吗?谢谢。


对于想尝试的人来说,有一些硬件要求。您需要带有 AVX FMA 指令集的 x86-64。

【问题讨论】:

  • 旧版本的 gcc 肯定会在 #error 上中止编译,所以不清楚这是功能还是回归
  • 通常认为编译器报告所有错误更有用,而不仅仅是第一个错误,因此您可以在再次编译之前修复所有问题。
  • 不幸的是,当由于依赖而出现错误时,第一个错误可能会导致其他错误的级联,这可能很烦人。但你不能两全其美。
  • 有一个 5yo feature request 来改变行为。
  • @Barmar #error 表示由于编译器配置出现问题,编码人员有意停止编译。就像编译时断言一样。任何后续消息都是无用的。

标签: c gcc compilation c-preprocessor avx


【解决方案1】:

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

实现不能成功翻译包含#error 预处理指令的预处理翻译单元,除非它是条件包含跳过的组的一部分。

稍后,在 §6.10.5 中,#error 被正式定义,它说

形式的预处理指令 # error pp-tokens opt new-line 导致实现生成包含指定的诊断消息 预处理标记序列。

换句话说,规范只要求任何具有#error 的代码只需要编译失败并在此过程中报告错误消息,而不是在#error 出现时立即终止编译到达。

鉴于始终检查编译器报告的顶级错误之前被认为是一种很好的做法,我想一个有能力的程序员看到一串以#error 指令开头的错误可能会知道什么是继续。

【讨论】:

  • 这是一个实现质量问题......如果编译器以“哈哈你的程序很糟糕”的消息响应任何错误,它也将符合要求
  • @MM 我可以想象一个合理的编译器作者选择继续编译以报告它遇到的任何其他错误,以防源文件存在其他问题,尽管你是对的,它可能不是最好的打电话。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-15
  • 2022-01-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-05
相关资源
最近更新 更多