【问题标题】:Desired effect of value-discarded comparision of GCC anonymous function variables' addresses [duplicate]GCC匿名函数变量地址的值丢弃比较的期望效果[重复]
【发布时间】:2016-05-18 10:24:06
【问题描述】:

Linux 内核定义了许多用于类型中性数值运算的辅助宏。即宏minmax定义为(在include/linux/kernel.h中)

#ifndef max
#define max(x, y) ({ \
        typeof(x) _max1 = (x); \
        typeof(y) _max2 = (y); \
        (void) (&_max1 == &_max2); \
        _max1 > _max2 ? _max1 : _max2; })
#endif
#ifndef min
#define min(x, y) ({ \
        typeof(x) _min1 = (x); \
        typeof(y) _min2 = (y); \
        (void) (&_min1 == &_min2); \
        _min1 < _min2 ? _min1 : _min2; })
#endif

扩展时,它们会生成匿名函数,这些函数执行操作类型中性和表达式分配安全的方式(使用 GCC 匿名函数)。到目前为止,一切都很好。令我惊讶的是这些宏产生的倒数第二个表达式:

   (void) (&_min1 == &_min2);

比较匿名函数范围内定义的临时变量的地址,然后丢弃结果; (void) 演员表防止出现任何警告。

我想知道这是什么期望的副作用?天真地我希望这会得到优化,因为它没有副作用(至少我不知道)。

【问题讨论】:

  • 获取地址通常会强制将值转储到内存中。您不能获取寄存器变量的地址

标签: c


【解决方案1】:

如果两个变量的类型不同,编译器会报错==。所以我怀疑这是为了确保这些值真的可以比较。

试试:

int i;
char *p;
(void)min(i, p);

是的,除了-O0 之外的任何优化级别都将优化该操作。

【讨论】:

  • 哦!当然。 :) – OTOH:我想知道这有多大意义?例如,我认为将signed longsigned char 进行比较没有问题,根据整数提升规则,该操作将signed char 提升为signed long。而且我可以想到很多情况,人们可能想要进行这样的比较。
  • @datenwolf:问题是,你要么全有,要么一无所有。没有它,您还可以比较例如int 和指针,因为转换规则。也许这对于较旧的编译器(C99 之前)更需要触发,这些编译器对触发的满意度要低得多(并且请求警告的选项也少得多)。如果你想比较兼容的类型,你仍然可以转换一个参数,即使是typeof()
  • @machine_1:不要更改正确的语法。
猜你喜欢
  • 2016-03-27
  • 2016-07-02
  • 2016-12-19
  • 1970-01-01
  • 2011-08-20
  • 2016-11-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多