(v) 实际上是(*&;v)从什么时候开始的? < C++标准大师>请启发我:< /P> < > C++标准版本有此语句失败,因为(v)< /> >似乎等同于(*&V)< /C> > /P>

(v) 实际上是(*&;v)从什么时候开始的? < C++标准大师>请启发我:< /P> < > C++标准版本有此语句失败,因为(v)< /> >似乎等同于(*&V)< /C> > /P>,c++,c++11,c++14,c++17,C++,C++11,C++14,C++17,例如,代码: #define DEC(V) ( ((V)>0)? ((V)-=1) : 0 ) ...{... register int v=1; int r = DEC(v) ; ...}... 这将在-std=c++17下产生警告,如: 无法获取寄存器变量的地址 操作数的左侧必须是左值 许多C宏都将所有宏参数括在括号中,以上只是其中的一个代表性示例 例如,产生警告的实际宏是 /usr/include/linux/rtnetlink.h中的RTA.

例如,代码:

 #define DEC(V) ( ((V)>0)? ((V)-=1) : 0 )
 ...{...
        register int v=1;
        int r = DEC(v) ;
 ...}...
这将在
-std=c++17
下产生警告,如:

无法获取寄存器变量的地址

操作数的左侧必须是左值

许多C宏都将所有宏参数括在括号中,以上只是其中的一个代表性示例

例如,产生警告的实际宏是
/usr/include/linux/rtnetlink.h
中的
RTA.*


<>没有使用/重新定义C++中的宏,有什么解决办法吗?

< p>如果你查看最新的C++ 1Z草稿的修订摘要,你会在

中看到这个。 [dcl.stc]
更改:删除寄存器存储类说明符。
理由:允许将来重新调整不推荐使用的关键字的用途 本国际标准的修订版。
<强>对原始特征的影响:< /强>使用登记的C++ 2014有效声明 本国际标准中的存储类说明符格式不正确。 说明符可以简单地删除以保留原始含义


警告可能是由于这个原因。

您的担心是没有根据的,因为所讨论的文件实际上不包含
注册表
关键字:

grep "register" /usr/include/linux/rtnetlink.h
什么也不输出。无论如何,您都不应该收到警告,因为:

  • 默认情况下,系统头不会发出警告,至少在GCC中是这样

  • 在C++模式下编译一个属于Linux内核的系统项目是不明智的,因为可能有微妙和令人讨厌的突破变化


只需正常地包含文件或将C代码链接到C++二进制。如果您确实收到了通常应该禁止的警告,请向编译器供应商报告错误。

寄存器不再是存储类说明符,您应该删除它。编译器可能没有发出正确的错误或警告,但您的代码不应首先注册

下面引用了标准中的一段话,告知人们应该如何处理代码中的
注册
(强调了相关部分),您可能有该文件的旧版本

C.1.6第10条:声明[diff.dcl]

变更:在C++中,登记不是存储类说明符。

理论:存储类说明符在C++中没有任何效果。 对原始特征的影响:删除语义上定义良好的特征

转换难度:句法转换

使用范围:普通


@ildjarn对不起,那有什么意义呢?似乎回答“我的问题总是在他们的结尾有疑问”。C有这样的规则,“登记”变量可能不是操作符地址的操作数,但是C++没有,C++用的关键字被删除了,所以编译器可能遵循C规则。但很明显,你的代码中没有运算符的地址,所以我建议你删除所有的点,并为我们提供一个完整的最小示例来重现你的错误消息。我无法重现该警告,使用
g++-std=c++17-fPIC-g-Wall-Wextra-Wwrite strings-Wno圆括号-Wpedantic-Warray bounds-Weffc++
和一个类似于
#define DEC(V)((V)>0?((V)-=1):0)int main(){register int V=1;int r=DEC(V);return r;}
。这是在g++版本6.3.0中。生成警告的实际宏,以及我的默认flsgs设置“-Wall-Wextra-Werror”,是:#define RTA\u ALIGNTO 4U#define RTA\u ALIGN(len)((len)+RTA\u ALIGNTO-1)&~(RTA\u ALIGNTO-1))#define RTA\u OK(RTA,len)((len>=(int)sizeof(struct rtattr)&(RTA)->rta\u len>=sizeof(struct rtattr)&&\(rta)->rta\u len,rta\u len,\(struct rtattr*)(((char*)(rta))+rta\u ALIGN((rta)->rta\u len))什么。。。问题是否与标题有关?问题中从未假设“rtnetlink.h”文件包含
register
,而是与该(已弃用)关键字的使用冲突的宏。好的,非常感谢所有的回答,我可以做:#如果GNUCXX>某个#值#定义寄存器#endif@JVD:如果
,则在
中没有点。事实上,相反的情况可能会发生。像
auto
register
可能会重新调整用途,以获得更有用的语言功能。啊哈!谢谢你指出这一点。但是对于'-std=gnu++17',这仍然是真的吗?调查…还可以看到,既然
register
不再是存储类说明符,您如何告诉编译器您希望在寄存器中存储某些内容?您不需要,@Venemo。很长一段时间以来,您都无法告诉编译器这一点。没有大的损失;优化器在寄存器分配方面做出的决策比您所能做的要好得多。就显而易见的意义而言,
寄存器
存储类说明符被编译器忽略了。这意味着,如果您试图获取这样声明的变量的地址,编译器将产生错误。哦,对不起。你完全正确,@T.C.只有C标准才使得获取
寄存器的地址
变量成为错误。在C++(当然是C++ 17之前),当你使用这个变量的地址时,代码>登记器< /COD>被编译器忽略。