【问题标题】:what is the use of "static_cast<void>" in macro?宏中的“static_cast<void>”有什么用?
【发布时间】:2015-06-23 06:13:04
【问题描述】:

我看到这样的宏定义:

#define ASSERT_VALID_PARAM(param, assertion) {  static_cast<void>(param); if (!(assertion)) { throw InvalidParamError(#param, #assertion, __FILE__, __PRETTY_FUNCTION__, __LINE__); } }

我无法在这里弄清楚static_cast&lt;void&gt;(param) 的需求。 知道为什么需要这样做吗?

【问题讨论】:

  • 这应该会有所帮助:cppreference -- static_cast
  • 宏应该使用do ... while(0)
  • @jxh,do..while(0) 用于处理“if(cond) MACRO”之类的用法,其中 MACRO 有多于一行。但是 MACRO 定义中的附加花括号应该可以处理相同的问题。
  • 除非它没有。如果没有do..while(0),添加else 是错误的。
  • @jxh,是的,你是对的。感谢您指出这一点。

标签: c++ casting


【解决方案1】:

此宏旨在验证某个 real 参数是否通过了某个验证规则。宏的逻辑部分由两部分组成:

  1. 验证param 是一个真实参数,具有有效的名称。这是通过使用static_cast 来完成的,如果使用了非法名称,则会产生编译时错误。
  2. 验证assertion 的“真实性”。这是通过一个简单的否定 if 语句完成的。

如果参数是有效名称,并且断言失败 (assertion == false),则会抛出 InvalidParamError,使用传入的参数作为字符串(使用 Stringizing operator #)来初始化错误对象。

由于宏中param参数的实际使用只是作为字符串,所以必须使用实际代码进行验证。由于不需要实际操作,因此使用了 static_cast,它会丢弃结果并且可能会被优化掉。如果没有该检查,您可以传递任何会使断言中的信息变得毫无意义的值。

【讨论】:

    【解决方案2】:

    这是'c++方式'的写作方式

    (void)param;
    

    它会“使用”变量,从而禁用未使用变量的编译器警告

    【讨论】:

    • assertion 是干什么用的? (宏有两个参数)。
    • 这不是它存在的原因。事实上,这是不可避免的缺点,否则未使用的变量可能会在没有警告的情况下通过。
    • @barak mano:你什么意思? assertion 的用途从上面的宏定义中就很明显了。
    • 是的,但这似乎与您在回答中提到的抑制编译器警告的目的完全无关。为什么这两个参数“加入”在同一个宏中?
    • 好吧,在删除那个 static_cast 之后我也没有收到任何编译器警告。
    【解决方案3】:

    static_cast&lt;void&gt;(param); 将评估 param 并丢弃结果。

    如果您不将演员表添加到void

    1. 您可能会收到警告说您忽略了 表达。
    2. 即使您传递一些非法代码(例如语句而不是表达式)作为参数,编译器也会愉快地接受它。

    来自cppreference

    4) 如果 new_type 是 void 类型(可能是 cv-qualified),static_cast 评估后丢弃表达式的值。

    【讨论】:

    • assertion 是干什么用的? (宏有两个参数)。
    • @barakmanos 可能是ASSERT_VALID_PARAM(++validCountDebug, sizeof(int) &gt;= 4)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-05-04
    • 2018-04-25
    • 2011-10-31
    • 2020-03-21
    • 2020-06-24
    • 1970-01-01
    • 2014-05-29
    相关资源
    最近更新 更多