Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/58.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C (void)0为什么停止;“声明无效”;警告?_C_Macros - Fatal编程技术网

C (void)0为什么停止;“声明无效”;警告?

C (void)0为什么停止;“声明无效”;警告?,c,macros,C,Macros,我有一个trace() #ifdef TRACE #define trace(x) trace_val(x, 0) #else #define trace(x) 0 #endif 当我调用trace()withtraceundefined时,这会从gcc生成warning:statement,但不起作用。经过一点搜索,我发现它正在改变 #define trace(x) 0 到 消除错误。我的问题是:为什么?有什么区别吗?对void的强制转换清楚地表明程序员打算丢弃结果。警告的

我有一个
trace()

#ifdef TRACE
    #define trace(x) trace_val(x, 0)
#else
    #define trace(x) 0
#endif
当我调用
trace()
with
trace
undefined时,这会从gcc生成
warning:statement,但不起作用。经过一点搜索,我发现它正在改变

#define trace(x) 0


消除错误。我的问题是:为什么?有什么区别吗?

对void的强制转换清楚地表明程序员打算丢弃结果。警告的目的是指出该语句没有明显的效果,因此提醒程序员注意这一点很有用,以防它是无意的。此处的警告没有任何作用。

警告和解决方法是特定于编译器的。但是,您可以执行以下操作:

#define NOP do { } while(0)

#ifdef ENABLE_TRACE
    #define TRACE(x) trace_val(x, 0)
#else
    #define TRACE(x) NOP
#endif

这首先避免了潜在的问题。

这个
{}
是否会导致尾随分号出现问题<代码>跟踪(x);微量元素(y)
最终看起来像
{};{};..@cHao:这不是问题所在。它是
if(foo)trace(x);else迹(y)
The
{}
将结束
if
而将
else
挂起。这将使
x
处于未使用状态,如果这是
x
的唯一用法,则会导致警告。我喜欢:
((void)(false&&(x))
@David:聪明。为什么要投虚空?为了避免OP提出的警告
false
避免计算
x
,假设这是所需的。(你的解决方案也很有效。事实上,我想我更喜欢它。)Duplicate@OrgnlDave这个问题没有讨论为什么(void)0不同于0。我想它没有明确地说明。如果你读懂了,它会的。删除我的评论为时已晚,但别担心,这不是一个有意义的结束问题的投票。这是语言语法中有文档记录的一部分吗?与其说是语言语法,不如说是特定的编译器。警告在语言中没有规定,它们是编译器为使事情变得更容易而做的额外操作。无论是否有编译器的警告,代码中的两个语法在语言级别都是有效的;它们的意思基本上是一样的,只是在一种情况下,它更“明显”(在非常非正式的意义上)是故意的。这种警告在语言中没有规定。有些警告是,但这些警告是“这正式是一个错误,但我会让它溜走”。
#define NOP do { } while(0)

#ifdef ENABLE_TRACE
    #define TRACE(x) trace_val(x, 0)
#else
    #define TRACE(x) NOP
#endif