我正在为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行。有没有办法做到这一点?
答案 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 ++,那么有更好的方法来处理这个而不是定义。我会想到constexpr
和static_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)"
所以在源代码中没有可以归咎于错误的地方。