2016-08-24 67 views
0

我正在为Windows,Unix和Mac制作跨平台程序。为了能够使用特定于每个操作系统的东西,我使用#define,例如,在编译Windows时,我使用#define WINDOWS。为了确保不定义不存在的OS,或者至少是我的程序不支持,我用这个:在特定行处发生预处理器错误

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

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

+0

如何在第11行定义操作系统?只用(例如)#define WINDOWS?如果 – vadikrobot

+0

@vadikrobot我在第11行定义操作系统意味着我的程序中的第11行包含例如'#define WINDOWS'。 –

+0

如果此行不存在,您希望在此行上看​​到错误? – vadikrobot

回答

3

如果你想显示具体的行一个错误,如果有你的代码中没有定义的宏,尝试使用#行

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 } 
2

预处理器非常简单。您在此处唯一的选项是在错误消息中包含行号。因为如果#define这个数字在其他地方,你怎么能确定这个#define甚至被处理,因为这种情况会遗漏其他定义(你正在检查的操作系统)。另外,你不可能在同一个行号上定义所有的三个宏,除非你对这些东西都有单独的头文件,这看起来像一个非常脆弱的系统。底线是你无法弄清楚什么地方应该被定义,如果它从来没有被定义在第一位。

如果这是纯粹的C++,有更好的方法来处理这个比定义。我们想到了constexprstatic_assert,使用像Boost.Predef这样的标准设施似乎比手动定义这些东西更好。

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)" 

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