【问题标题】:Need help regarding macro definition需要有关宏定义的帮助
【发布时间】:2016-03-21 00:35:55
【问题描述】:

我正在阅读 c++ 代码,我找到了这样的定义

#define USE_VAL(X) if (&X-1) {}

有人知道吗,这是什么意思?

【问题讨论】:

  • 你是在用这个来摆脱未使用的参数警告吗?
  • 至于if - 作者可能试图这样做:stackoverflow.com/questions/154136/…
  • 我想知道这个是做什么用的,因为我有一个现有的代码,想使用这个代码
  • 基于它具有未定义行为并因此使整个程序无效的事实,我会远离包含它的代码。

标签: c++ function macros


【解决方案1】:

宏是一个预处理器指令,这意味着无论在哪里使用它,它都会被相关的代码片段替换。

在 USE_VAL(X) 之后的空格是解释 USE_VAL(X) 会做什么。

首先它获取 x 的地址,然后从中减去 1。如果为 0,则什么也不做。

将使用 USE_VAL(X) 的地方将替换为 if (&X-1) {}

【讨论】:

  • 宏不是函数。
  • 是的,宏不起作用。但是为了理解你可以使用这个概念来思考。
  • @KashifArif 不,不,。不要将宏视为函数。它们甚至远不接近。宏是纯粹的语法替换。像考虑函数一样考虑宏会导致各种错误和误解。
【解决方案2】:

根据名称,它看起来像是一种摆脱“未使用变量”警告的方法。预期用途可能是这样的:

int function(int i)
{
  USE_VAL(i)
  return 42;
}

如果没有这个,您可能会收到一个编译器警告,指出参数i 在函数中未使用。

然而,这是一种相当危险的方法,因为它在代码中引入了未定义的行为(超出实际数组范围的指针算术在标准中是未定义的)。可以 1 到对象的地址,但不能减 1。当然,使用+ 1 而不是- 1,编译器可以警告“条件始终为真”。 可能优化器将删除整个 if 并且代码将保持有效,但优化器在利用“无法发生未定义的行为”方面做得越来越好,这实际上可能会出乎意料地弄乱代码。

更不用说operator& 可能会因所涉及的类型而被重载,这可能会导致不良副作用。

有更好的方法来实现此类功能,例如转换为void

#define USE_VAL(X) static_cast<void>(X)

不过,我个人的偏好是把函数定义中的参数名称注释掉,像这样:

int function(int /*i*/)
{
  return 42;
}

这样做的好处是它实际上可以防止您在将参数传递给宏后意外使用它。

【讨论】:

  • 是的,对于最后一种方法。这是迄今为止最简单的,并且不涉及添加故意不执行任何操作以消除编译器警告的代码。
【解决方案3】:

通常是为了避免“未使用的返回值”警告。即使通常的“cast to void”习语通常适用于未使用的函数参数,gcc-pedantic 在忽略函数的返回值时特别严格,例如 fread(通常,标记为 __attribute__((warn_unused_result)) 的函数) ,所以“假的if”经常被用来欺骗编译器,让他们认为你正在用返回值做一些事情。

【讨论】:

  • 你不能获取右值的地址,所以这对于大多数返回值都不起作用。
猜你喜欢
  • 2021-09-06
  • 1970-01-01
  • 1970-01-01
  • 2021-10-31
  • 2015-06-23
  • 2014-12-26
  • 2013-08-12
  • 2014-06-11
  • 1970-01-01
相关资源
最近更新 更多