GCC #pragma 停止编译

问题描述 投票:0回答:8

是否有 GCC pragma 指令可以停止、暂停或中止编译过程?

我正在使用 GCC 4.1,但我希望该编译指示也可以在 GCC 3.x 版本中使用。

gcc
8个回答
63
投票

您可能想要

#error

$ cd /tmp
$ g++ -Wall -DGoOn -o stopthis stopthis.cpp
$ ./stopthis

Hello, world

$ g++ -Wall -o stopthis stopthis.cpp

stopthis.cpp:7:6: error: #error I had enough

文件stopthis.cpp

#include <iostream>

int main(void) {
  std::cout << "Hello, world\n";
  #ifndef GoOn
    #error I had enough
  #endif
  return 0;
}

23
投票

我不知道

#pragma
,但是
#error
应该做你想做的事:

#error Failing compilation

它将终止编译并显示错误消息“编译失败”。


15
投票

这有效:

 #include <stophere>

GCC 在找不到包含文件时停止。如果不支持 C++14,我希望 GCC 停止。

 #if __cplusplus<201300L
   #error need g++14
   #include <stophere>
#endif

7
投票

虽然通常

#error
就足够了(并且可移植),但有时您想要使用
pragma
,即当您想要选择在宏内引发错误时。

这是一个示例使用,取决于 C11 的

_Generic
_Pragma

此示例确保

var
不是
int *
short *
,但在编译时不是
const int *

示例:

#define MACRO(var)  do {  \
    (void)_Generic(var,   \
          int       *: 0, \
          short     *: 0, \
          const int *: 0 _Pragma("GCC error \"const not allowed\""));  \
    \
    MACRO_BODY(var); \
} while (0)

4
投票
#pragma GCC error "error message"

参考:7 指令


0
投票

您可以使用:

#pragma GCC error "my message"

但这不是标准。


0
投票

另一种方法是使用

static_assert
:

#if defined(_MSC_VER) && _MSC_VER < 1916
    static_assert(false, "MSVC supported versions are 1916 and later");
#endif

0
投票

正如一些人指出的,在没有解释为什么的情况下,

#error
不会立即停止编译。我认为为什么值得一些解释。

如果我们参考
this

C11草案,我们可以看到以下内容:

6.10.5
    错误指令
  • #error的行为是“导致实现生成包含指定的预处理标记序列的诊断消息。”
    4 
  • 一致性
  • §4“实现不应成功翻译包含 #error
     处理指令的预处理翻译单元,除非它是通过条件包含跳过的组的一部分”。
  • 因此,
#error

的实际实现取决于编译器。为了使实现保持一致,“必须”做的是生成诊断消息并且不成功翻译翻译单元。 GCC 两者都做到了,因此它的

#error
实现是一致的。 标准未指定实现是否
立即
停止编译。

如果我们查看 gcc,我们可以编译以下文件,error.c

:

#error Error void f(int a) { *a = 12; }

使用标准编译线

$ gcc -c error.c -o /dev/null                                      
error.c:1:2: error: #error Error
    1 | #error Error
      |  ^~~~~
error.c: In function ‘f’:
error.c:4:3: error: invalid type argument of unary ‘*’ (have ‘int’)
    4 |   *a = 12;
      |   ^~

GCC 发出两个错误,其中一个在

#error
 之后。显然,gcc并没有立即停止编译。 
Mosh

This
回答提供了一种立即停止编译的解决方法:包括不存在的标头。这被认为是一个“致命”错误(如“这个”答案中指出的),并且 gcc 在遇到致命错误时将立即停止编译。 #error 生成的错误不是致命的,因此允许 gcc 以任何它想要的方式继续处理输入。 要将 #error 变成即时编译停止,我们可以遵循相同的答案,只需将 -Wfatal-errors 添加到命令行,以便 gcc 在遇到任何类型的错误时立即停止。
$ gcc -c error.c -Wfatal-errors -o /dev/null 
error.c:1:2: error: #error Error
    1 | #error Error
      |  ^~~~~
compilation terminated due to -Wfatal-errors.

请注意,

-Wfatal-errors
仅适用于 GCC 4.x 及以上版本。对于 GCC 3.x 及更早版本,包含不存在标头的 mosh 解决方案仍然是最佳解决方案。总的来说,mosh 的解决方案巧妙地解决了这个问题:它适用于所有版本的 GCC,并且不会将每个错误都变成立即停止。
    

© www.soinside.com 2019 - 2024. All rights reserved.