C++ 为什么在发布版本中,assert宏的定义不能仅仅是`#define assert(expression)0`?

C++ 为什么在发布版本中,assert宏的定义不能仅仅是`#define assert(expression)0`?,c++,c,visual-studio,assert,C++,C,Visual Studio,Assert,这是Visual Studio 2019中assert宏的定义 #ifdef NDEBUG #define assert(expression) ((void)0) #else _ACRTIMP void __cdecl _wassert( _In_z_ wchar_t const* _Message, _In_z_ wchar_t const* _File, _In_ unsigned _Line

这是Visual Studio 2019中assert宏的定义

#ifdef NDEBUG

    #define assert(expression) ((void)0)

#else

    _ACRTIMP void __cdecl _wassert(
        _In_z_ wchar_t const* _Message,
        _In_z_ wchar_t const* _File,
        _In_   unsigned       _Line
        );

    #define assert(expression) (void)(                                                       \
            (!!(expression)) ||                                                              \
            (_wassert(_CRT_WIDE(#expression), _CRT_WIDE(__FILE__), (unsigned)(__LINE__)), 0) \
        )

#endif
如上所示,发布版本中宏断言的定义是

#define assert(expression) ((void)0)

为什么不能定义断言(表达式)0呢?

这就阻止了将
断言
用作表达式。因此,如果有人(错误地)这样做:


编译器将为发布版本和调试版本抛出错误。

某些编译器可能希望使用
(void)
强制转换来抑制有关未使用其值的表达式的警告。

相关:。(不是重复,因为它关注的是另一个备选方案,但它可能会引起未来发现这个问题的人的兴趣。)@JaMiT I对链接问题中给出的答案并不信服。所以我决定在一次面试中问同样的问题。我得到了伊戈尔·坦德尼克的精彩回答。*耸耸肩*伊戈尔确实给出了一个很好的例子。但是,您可能会注意到,在这个页面的某个地方(在宽浏览器中位于右侧,在窄浏览器中位于底部),现在有一个“链接”部分,其中有一个链接指向“为什么将断言定义为(void)0?”。我可以通过添加评论向该部分添加相关的SO问题。添加一个相关的非SO问题并不是那么简单我花了一段时间才接受你说的话。但你的答案是正确的。顺便说一句,回答得很好@贝洛克:不一定只有一个“正确”的答案;可能有多种原因。而且,这个答案有点不准确。
(void)
强制转换可以防止
assert()
成为右值,但它仍然可以用作表达式。例如:
条件?assert(某物):assert(某物)
assert(条件),puts(“hello”)
@jamesdlin你会发现我接受朱利安而不是你答案的原因。基本上,朱利安的回答似乎更好地解释了这个例子,因为在这个案例中没有任何警告。我还注意到朱利安的回答有点不准确。但在我看来,这是一个非常小的问题,不能做出对他有利的决定。
a = assert(something);