C语言 有没有办法同时检查宏是否定义并且等于某个值
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17160755/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Is there a way to both check a macro is defined and it equals a certain value at the same time
提问by gbmhunter
I regularly use object-like preprocessor macros as boolean flags in Ccode to turn on and off sections of code.
我经常使用类对象预处理器宏作为C代码中的布尔标志来打开和关闭代码部分。
For example
例如
#define DEBUG_PRINT 1
And then use it like
然后像这样使用它
#if(DEBUG_PRINT == 1)
printf("%s", "Testing");
#endif
However, it comes a problem if the header file that contains the #defineis forgotten to be included in the source code. Since the macro is not declared, the preprocessor treats it as if it equals 0, and the #ifstatement never runs.
但是,如果#define忘记包含在源代码中的头文件,就会出现问题。由于未声明宏,预处理器将其视为等于 0,并且#if语句永远不会运行。
When the header file is forgotten to be included, non-expected, unruly behaviour can occur.
当忘记包含头文件时,可能会发生意外的、不守规矩的行为。
Ideally, I would like to be able to both check that a macro is defined, and check that it equals a certain value, in one line. If it is not defined, the preprocessor throws an error (or warning).
理想情况下,我希望能够在一行中检查是否定义了宏,并检查它是否等于某个值。如果未定义,预处理器将抛出错误(或警告)。
I'm looking for something along the lines of:
我正在寻找以下方面的东西:
#if-def-and-true-else-throw-error(DEBUG_PRINT)
...
#endif
It's like a combination of #ifdefand #if, and if it doesn't exist, uses #error.
它就像#ifdefand的组合#if,如果它不存在,则使用#error。
I have explored a few avenues, however, preprocessor directives can't be used inside a #defineblock, and as far as I can tell, there is no preprocessor option to throw errors/warnings if a macro is not defined when used inside a #ifstatement.
我已经探索了一些途径,但是,预处理器指令不能在#define块内使用,据我所知,如果在#if语句中使用时未定义宏,则没有预处理器选项可以抛出错误/警告。
采纳答案by Michael Burr
This may not work for the general case (I don't think there's a general solution to what you're asking for), but for your specific example you might consider changing this sequence of code:
这可能不适用于一般情况(我认为您所要求的没有通用解决方案),但对于您的具体示例,您可能会考虑更改以下代码序列:
#if(DEBUG_PRINT == 1)
printf("%s", "Testing");
#endif
to:
到:
if (DEBUG_PRINT == 1) {
printf("%s", "Testing");
}
It's no more verbose and will fail to compile if DEBUG_PRINTis not defined or if it's defined to be something that cannot be compared with 1.
它不再冗长,如果DEBUG_PRINT未定义或定义为无法与1.
回答by jamesdlin
as far as I can tell, there is no preprocessor option to throw errors/warnings if a macro is not defined when used inside a
#ifstatement.
据我所知,如果在
#if语句中使用时未定义宏,则没有预处理器选项可以抛出错误/警告。
It can't be an error because the C standard specifies that behavior is legal. From section 6.10.1/3 of ISO C99 standard:
这不会是错误,因为 C 标准规定行为是合法的。来自 ISO C99 标准的第 6.10.1/3 节:
After all replacements due to macro expansion and the
definedunary operator have been performed, all remaining identifiers are replaced with the pp-number0....
在执行了由于宏扩展和
defined一元运算符导致的所有替换之后,所有剩余的标识符都被替换为 pp-number0....
As Jim Balter notes in the comment below, though, some compilers (such as gcc) can issue warnings about it. However, since the behavior of substituting 0for unrecognized preprocessor tokens is legal (and in many cases desirable), I'd expect that enabling such warnings in practice would generate a significant amount of noise.
不过,正如 Jim Balter 在下面的评论中指出的那样,一些编译器(例如 gcc)可能会发出警告。但是,由于替换0无法识别的预处理器令牌的行为是合法的(并且在许多情况下是可取的),我预计在实践中启用此类警告会产生大量噪音。
There's no way to do exactly what you want. If you want to generate a compilation failure if the macro is not defined, you'll have to do it explicitly
没有办法完全按照您的意愿行事。如果要在未定义宏的情况下生成编译失败,则必须显式执行
#if !defined DEBUG_PRINT
#error DEBUG_PRINT is not defined.
#endif
for each source file that cares. Alternatively, you could convert your macro to a function-like macro and avoid using #if. For example, you could define a DEBUG_PRINTmacro that expands to a printfcall for debug builds but expands to nothing for non-debug builds. Any file that neglects to include the header defining the macro then would fail to compile.
对于每个关心的源文件。或者,您可以将宏转换为类似函数的宏并避免使用#if. 例如,您可以定义一个DEBUG_PRINT宏,该宏扩展为printf调用调试版本,但对于非调试版本扩展为无。任何忽略包含定义宏的头文件的文件都将无法编译。
Edit:
编辑:
Regarding desirability, I have seen numerous times where code uses:
关于可取性,我已经多次看到代码使用:
#if ENABLE_SOME_CODE
...
#endif
instead of:
代替:
#ifdef ENABLE_SOME_CODE
...
#endif
so that #define ENABLE_SOME_CODE 0disables the code rather than enables it.
这样会#define ENABLE_SOME_CODE 0禁用代码而不是启用它。
回答by Jim Balter
Rather than using DEBUG_PRINT directly in your source files, put this in the header file:
与其在源文件中直接使用 DEBUG_PRINT,不如将其放在头文件中:
#if !defined(DEBUG_PRINT)
#error DEBUG_PRINT is not defined
#endif
#if DEBUG_PRINT
#define PrintDebug([args]) [definition]
#else
#define PrintDebug
#endif
Any source file that uses PrintDebug but doesn't include the header file will fail to compile.
任何使用 PrintDebug 但不包含头文件的源文件都将无法编译。
If you need other code than calls to PrintDebug to be compiled based on DEBUG_PRINT, consider using Michael Burr's suggestion of using plain ifrather than #if(yes, the optimizer will not generate code within a false constant test).
如果您需要其他代码而不是基于 DEBUG_PRINT 编译对 PrintDebug 的调用,请考虑使用 Michael Burr 的建议,即使用普通if而不是#if(是的,优化器不会在错误常量测试中生成代码)。
Edit: And you can generalize PrintDebug above to include or exclude arbitrary code as long as you don't have commas that look like macro arguments:
编辑:并且您可以概括上面的 PrintDebug 以包含或排除任意代码,只要您没有看起来像宏参数的逗号:
#if !defined(IF_DEBUG)
#error IF_DEBUG is not defined
#endif
#if IF_DEBUG
#define IfDebug(code) code
#else
#define IfDebug(code)
#endif
Then you can write stuff like
然后你可以写这样的东西
IfDebug(int count1;) // IfDebug(int count1, count2;) won't work
IfDebug(int count2;)
...
IfDebug(count1++; count2++;)
回答by Eugen Konkov
Yes you can check both:
是的,您可以同时检查:
#if defined DEBUG && DEBUG == 1
# define D(...) printf(__VA_ARGS__)
#else
# define D(...)
#endif
In this example even when #define DEBUG 0but it is not equal to 1 thus nothing will be printed.
在此示例中,即使#define DEBUG 0但它不等于 1,因此不会打印任何内容。
You can do even this:
你甚至可以这样做:
#if defined DEBUG && DEBUG
# define D(...) printf(__VA_ARGS__)
#else
# define D(...)
#endif
Here if you #define DEBUG 0and then D(1,2,3)also nothing will be printed
在这里,如果您#define DEBUG 0然后D(1,2,3)也不会打印任何内容
回答by Lundin
Simply create a macro DEBUG_PRINT that does the actual printing:
只需创建一个宏 DEBUG_PRINT 来进行实际打印:
#define DEBUG_PRINT(n, str) \
\
if(n == 1) \
{ \
printf("%s", str); \
} \
else if(n == 2) \
{ \
do_something_else(); \
} \
\
#endif
#include <stdio.h>
int main()
{
DEBUG_PRINT(1, "testing");
}
If the macro isn't defined, then you will get a compiler error because the symbol is not recognized.
如果未定义宏,则您将收到编译器错误,因为无法识别该符号。
回答by Sam Keith
#if 0 // 0/1
#define DEBUG_PRINT printf("%s", "Testing")
#else
#define DEBUG_PRINT printf("%s")
#endif
So when "if 0" it'll do nothing and when "if 1" it'll execute the defined macro.
所以当“if 0”它什么都不做,当“if 1”它会执行定义的宏。

