c++ - Visual Studio 2010 SP1 中的断言和未使用的变量

标签 c++ visual-studio-2010 macros assert

我使用下面的代码在“发布”中断言,有一段时间没有出现任何问题。 然后出现了 Visual Studio 2010 Pro SP1,事情变得很糟糕,as also happened to mr. Krunthar .

问题是,当我有一段代码在其中进行完整性检查时:

#define ASSERT(condition, msg) do { (void)sizeof(condition); } while (0,0)
  // Note: (0,0) is to avoid warning C4127: conditional expression is constant

{
  int result = CallMeOnce();  // its side effects are the important stuff
  // perform additional sanity checks in debug
  ASSERT(result >= 0, "too low");
  ASSERT(result <= 100, "too high");
  ASSERT(!isPrime(result), "too prime");
}

VS2010 发出 warning C4189: 'result' : local variable is initialized but not referenced

我不知道如何解决这个问题:

  • (void)(condition) 之类的代码将执行作为条件传递的任何表达式,这是一个 no no
  • 不可能将 CallMeOnce() 放在 ASSERT 表达式中
  • 重构所有不同的 CallMeOnce() 不是一种选择
  • 我宁愿不必编写像 (void)resultif (result == result) {}UNREFERENCED_PARAMETER(result) 这样的脚手架代码 (或等价物)在宏之外只是为了避免警告,因为它使代码更难阅读(污染),并且在 Debug 中编写代码时很容易忘记。还有:在很多地方!

我正在考虑为变量创建另一个宏(ASSERTU?),但感觉太……古怪了!
有没有人找到更好的出路?

非常感谢!

编辑:阐明了调用者级别变量处理的偏好

最佳答案

在你的断言宏中你有

(void)sizeof(condition);

估计这段代码是别人写的,所以,解释一下:

(void) 转换的作用是告诉编译器您确实打算让这个什么也不做的表达式语句什么都不做。

现在对你的结果做同样的事情

这很容易,不是吗?有时解决方案只是盯着你看。 ;-)


顺便说一句,当这个构造用于抑制关于未使用的形式参数的警告时,您可能想要添加名称的重新定义,例如

(void) unusedArg; struct unusedArg;

这可以防止在以后维护代码时无意中使用参数

然而,visual c++ 生成的错误并不完全是信息性的


可以添加无数级别的复杂性,但我认为即使是名称重新定义也可能太过分了——成本可能大于优势

关于c++ - Visual Studio 2010 SP1 中的断言和未使用的变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15819292/

相关文章:

没有参数的 C++ 可变参数函数

C++ 与 Dll 通信出错

c# - 我需要帮助了解 C# 项目在 Visual Studio 中的组织方式

c++ - C++ 函数默认参数的位置

syntax - 非 Lisp 语言中有哪些宏系统?

compiler-errors - 使用关键字的一部分提取SAS中的完整关键字

c++ - 我应该声明我的函数模板特化还是定义它们就足够了?

c++ - SDL/SDL.h : No such file or directory

c++ - "warning C4987: nonstandard extension used: ' throw (... )'"是什么意思?

ios - 如何制作宏?