3

问题

我使用了一个空的声明并且知道这一点。那么如何禁用编译器警告呢?

警告 C4390:';' : 找到空的受控语句;这是意图吗?

可能有一种方式可以明确地说我想要一个空语句。

背景

在开发环境中,调试功能应显示错误消息并退出应用程序。在生产版本中,它应该什么都不做。所以我为此写了一个宏。

#ifdef _DEBUG
#include <iostream>
#define Debug(text) { cout << "Error: " << text; cin.get(); exit(1); }
#else
#define Debug(text) ;
#endif
4

5 回答 5

4

空语句宏的常见习语是:

#define Debug(text) do {} while (0)

正如 Ben 在评论中指出的那样,在宏的两个版本中使用这种技术是谨慎的。

#ifdef _DEBUG
#include <iostream>
#define Debug(text) do { cout << "Error: " << text; cin.get(); exit(1); } while (0)
#else
#define Debug(text) do {} while (0)
#endif

这个成语在很多地方都有讨论。例如:

于 2012-12-18T18:42:00.850 回答
3

您可以明确告诉编译器您没有做任何事情

(void)0;
于 2012-12-18T18:47:45.797 回答
0

Debug用作类似函数的宏,但不像一个宏:

if( some_condition ) Debug(); else { blah }    // Ooops

此外,它与标准输出流混淆,包含用于调试和发布构建的不同标头,使用保留符号(以下划线开头,后跟大写)_DEBUG(您的意思是使用标准NDEBUG吗?)并且不必要地使用非标准退出值。

因此,而不是当前

#ifdef _DEBUG
#include <iostream>
#define Debug(text) { cout << "Error: " << text; cin.get(); exit(1); }
#else
#define Debug(text) ;
#endif

#ifndef DEBUGGING_H
#define DEBUGGING_H

#include <iostream>      // std::cerr, std::endl
#include <stdlib.h>      // exit, EXIT_FAILURE

#ifdef MYDEBUG
#   define Debug(text) ::debugging::sayByeAndTerminate( text )
#else
#   define Debug(text)
#endif

namespace debugging {
    inline void sayByeAndTerminate( char const* const text )
    {
        using namespace std;
        cerr << "Error: " << text; cin.get(); exit(EXIT_FAILURE);
    }
}  // namespace debugging

注意上面的代码没有使用傻

do {} while( false )

也不是双傻

(void)0

因为没有必要为了一无所获而写一些东西。

没有什么是完美无缺的。

对于警告:我无法使用 Visual C++ 11 重现它(请提供一个展示该行为的完整示例),但只需将其关闭即可。不要调整代码以适应编译器。只需关闭警告即可。

免责声明:即兴代码,编译器未触及。

于 2012-12-18T18:54:05.270 回答
0

另一个什么都不做的明确表达:

void();

此语法使用 C++ 默认构造函数作为void类型,因此它在 C 中不起作用。

它是包含单词的最短有效代码void,因此可能略好于(void)0.

于 2019-12-29T09:47:58.630 回答
0

禁用编译警告的另一种方法是在代码开头添加以下内容:

#pragma warning( disable : 4390 )
于 2021-10-26T09:08:09.980 回答