C ++标准专家能不能启发我:
由于(v)
似乎等同于(*&v)
,因此哪个C ++标准版本的语句失败?
即。例如代码:
#define DEC(V) ( ((V)>0)? ((V)-=1) : 0 )
...{...
register int v=1;
int r = DEC(v) ;
...}...
现在会在-std=c++17
下生成警告,如:
不能取寄存器变量的地址
操作数的左侧必须是左值
许多C宏将括号中的所有宏参数括起来,其中上述仅仅是一个代表性的例子。
例如,产生警告的实际宏
RTA_*
中的/usr/include/linux/rtnetlink.h
个宏。
如果没有在C ++中使用/重新定义这些宏,是否有任何解决方法?
答案 0 :(得分:16)
如果您查看最新C ++ 1z草案的修订摘要,您会在[diff.cpp14.dcl.dcl]
中看到这一点。[dcl.stc]
更改:删除寄存器存储类说明符 理由:以后启用已弃用关键字的重新调整用途 本国际标准的修订 对原始功能的影响:使用该寄存器的有效C ++ 2014声明 存储类说明符在本国际标准中不正确。 可以简单地删除说明符以保留原始含义。
警告可能是由于此。
答案 1 :(得分:13)
register
不再是存储类说明符,您应该删除它。编译器可能没有发出正确的错误或警告,但您的代码不应该以{{1}}开头
以下是标准的引用,告知人们他们应该在代码中对register
做些什么(相关部分强调),你可能有该文件的旧版本
C.1.6第10条:声明[diff.dcl]
更改:在C ++中,register不是存储类说明符。
基本原理:存储类说明符对C ++没有影响。 对原始特征的影响:删除语义明确定义的特征。
难以转换:语法转换。
使用范围广泛:普通。
答案 2 :(得分:6)
您的担心是没有根据的,因为相关文件实际上并不包含register
关键字:
grep "register" /usr/include/linux/rtnetlink.h
什么都不输出。无论哪种方式,您都不应该收到警告:
默认情况下,系统标头不会发出警告,至少在GCC中
在C ++模式下尝试编译属于Linux内核等系统项目的文件是不明智的,因为可能存在微妙且令人讨厌的重大变化
只需正常包含文件或将C代码链接到C ++二进制文件即可。如果您确实收到通常应该被抑制到编译器供应商的警告,请报告错误。