在特定行生成预处理器错误

时间:2016-08-24 08:21:14

标签: c++ c c-preprocessor

我正在为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行。有没有办法做到这一点?

3 个答案:

答案 0 :(得分:3)

如果您希望在代码中没有定义的宏时在特定行显示错误,请尝试使用 #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 }

答案 1 :(得分:2)

预处理器非常简单。您在这里唯一的选择是在错误消息中包含行号。因为如果你在其他地方#define那个号码,你怎么确定这个#define甚至被处理了,因为这个场景错过了其他定义(你正在检查的操作系统)。此外,您无法在同一行号上定义所有三个宏,除非您为这些内容中的每一个都有单独的标头,这看起来像一个非常脆弱的系统。最重要的是,如果首先从未定义某些东西,你就无法确定应该在哪里定义。

如果这是纯C ++,那么有更好的方法来处理这个而不是定义。我会想到constexprstatic_assert,使用像Boost.Predef这样的标准设施似乎比手动定义这些内容更好。

答案 2 :(得分:0)

如果改变逻辑,你或许可以做你想做的事情(但是没有任何保证)。

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

如果定义了宏,许多编译器会警告您重新定义,并确切地说明可以找到第一个定义的位置。但是,这并不能保证。

当然,如果从未定义过操作系统,那么甚至没有理论上可以确定定义的位置。如果您知道应该定义的位置,您可以使用__LINE____FILE__指令将编译器定向到该位置:

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

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

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

所以在源代码中没有可以归咎于错误的地方。