在特定行上产生预处理器错误

Make a preprocessor error at a specific line

本文关键字:预处理 处理器 错误      更新时间:2023-10-16

我正在为Windows, Unix和Mac制作一个跨平台程序。为了能够使用每个操作系统特定的东西,我使用#define,例如,当我为Windows编译时,我使用#define WINDOWS。为了确保不定义一个不存在的操作系统,或者至少是我的程序不支持的操作系统,我使用如下:

#ifndef WINDOWS
#ifndef UNIX
#ifndef MAC
#error "OS must be WINDOWS, UNIX or MAC"
#endif
#endif
#endif

当我定义一个无效的操作系统时,它给了我一个错误,因为它应该,但它把红色矩形,这意味着错误在#error线前面。我想把它放在我定义操作系统的那行前面。例如,如果我应该在第11行定义操作系统,我希望它将我发送到第11行。有办法做到这一点吗?

如果您希望在代码中没有定义宏的情况下显示特定行上的错误,请尝试使用#line

1 #ifndef UNIX
2 #ifndef MAC
3 #line 11 
4 #error "OS must be WINDOWS, UNIX or MAC" 
5 #endif 
6 #endif 
7 #endif 
8    
9  int main ()
10 {
11   // here will be error from line 4
12 }

预处理器非常简单。这里唯一的选项是在错误消息中包含行号。因为如果您在其他地方#define这个数字,您如何确定这个#define甚至被处理,因为这个场景错过了其他定义(您正在检查的操作系统)。此外,您不可能在同一行号上定义所有三个宏,除非您为每一个宏都有单独的头文件,这似乎是一个非常脆弱的系统。最重要的是,如果一个东西从一开始就没有定义过,你就不知道应该在哪里定义它。

如果这是纯c++,有比定义更好的方法来处理它。想到constexprstatic_assert s,并使用Boost等标准工具。Predef似乎比手动定义这些东西更好。

如果你改变你的逻辑,你可能能够做你想做的(没有什么是可以保证的)。

C预处理器不知道哪个宏命名一个操作系统,哪个宏命名其他东西。没有办法捕获一个宏,您认为它命名了除您可以处理的三个操作系统之外的其他操作系统。与其使用多个可能的宏名,不如使用一个具有多个可能值的宏。现在,当您看到一个无法处理的值时,您可能可以做一些事情。

 #define WINDOWS 1002437 // a random magic number
 #define UNIX 2753321
 ...
 #define OS UNIX
 ...
 #if OS == WINDOWS
   ...
 #elseif OS == UNIX
   ...
 #elseif ...
  ...
 #else // here comes the trick
    #define OS 99997321
    #error "Bad OS"
 #endif

如果定义了一个宏,许多编译器会警告你它的重定义,并准确地指出在哪里可以找到第一个定义。然而,这并不能保证。

当然,如果OS从来没有定义过,那么在理论上就不可能精确地指出哪里没有定义。如果您知道应该在哪里定义,您可以使用__LINE____FILE__指令将编译器引导到该位置:

    #line 11
    #error "OS should be defined here"

然而,在实际的软件中,这些宏通常由编译器命令行定义,并由makefile或类似的文件控制。

   CPPFLAGS += "-DOS=$(OS_ID)"

所以源代码中没有地方可以为错误负责