【问题标题】:Does C's ternary conditional operator create a new scope?C 的三元条件运算符是否创建了新范围?
【发布时间】:2016-12-12 05:50:05
【问题描述】:

标题基本上说明了一切,但我特别想知道是否应该期望以下(稍微滥用)宏(使用 C99 或更高版本)工作,也就是说,它将返回一个指向有效部分的指针基于表达式大小的堆栈分配内存:

#include <stdint.h>

#define NASTY(expr) ( \
    8 == sizeof(expr) ? (void *)(&(uint64_t){(expr)}) : \
    ( \
        4 == sizeof(expr) ? (void *)(&(uint32_t){(expr)}) : \
        ( \
            2 == sizeof(expr) ? (void *)(&(uint16_t){(expr)}) : (void *)(&(uint8_t){(expr)}) \
        ) \
    ) \
)

编辑:

我对这样一个宏感兴趣的原因是 (1) 我是一个书呆子,并且 (2) 我正在为需要动态 memcpy 表达式结果的嵌入式应用程序编写一些代码生成宏(例如如x*y+z)。我们正在开发一个对能量敏感的应用程序,其中函数调用很重要。

【问题讨论】:

  • 给出一些用例示例。
  • 我的意思很好,但是为什么这个问题需要用宏来提出呢?为什么预处理器是相关的?还是您在利用非标准 c 的表达式语句?
  • 还有为什么三元运算符会相关?您只是在获取 something 的地址。
  • @EOF:复合文字左值。您可以获取他们的地址。
  • 范围如何与表达式有关?您实际上想知道“什么是范围”。

标签: c scope


【解决方案1】:

我不知道您所说的“新范围”是什么意思——在 C 中,“范围”仅与标识符相关,与对象生命周期无关。根据 6.5.2.5 复合文字,

如果复合文字出现在函数体之外,则对象具有静态存储持续时间;否则,它具有与封闭块关联的自动存储持续时间。

因此,如果您在函数体中使用此宏,则指向对象的生命周期将持续到封闭块的执行结束。这可能会也可能不会满足您的需求;你可能会因为这样写而惹上麻烦:

if (foo) {
    p = NASTY(bar);
}
/* ... */
/* Do something with p */

【讨论】:

  • 这正是我根据一些 Dr. Memory 测试所预期的行为。谢谢你的解释!
  • @Olaf:没有这样的事情。 static 不是类型的一部分;这是一个存储类。将static 放在复合文字的括号中只是一个语法错误。
  • @R..:感谢您提供的信息。我知道 static 在语法上是什么。如果它允许存储类说明符,我只是懒得检查复合文字的语法。如果指针被占用,我只是可以看到一些用法(但是,在睡眠之后,人们也可以使用static 变量,所以它会更像句法/语法糖)。
猜你喜欢
  • 2017-09-14
  • 2010-10-20
  • 1970-01-01
  • 2021-05-27
  • 2013-04-19
  • 2013-07-13
  • 2015-02-15
  • 2022-12-06
  • 2021-10-06
相关资源
最近更新 更多