(v)实际上是(*&v),因为什么时候?

JVD*_*JVD 17 c++ c++11 c++14 c++17

C++标准专家可以赐教我:

由于哪个C++标准版本有这个语句失败,因为(v)似乎相当于(*&v)

即代码:

 #define DEC(V) ( ((V)>0)? ((V)-=1) : 0 )
 ...{...
        register int v=1;
        int r = DEC(v) ;
 ...}...
Run Code Online (Sandbox Code Playgroud)

这现在产生如下警告-std=c++17:

不能取寄存器变量的地址

操作数的左侧必须是左值

许多C宏将括号中的所有宏参数括起来,其中上述仅仅是代表性示例.

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

如果没有在C++中使用/重新定义这些宏,是否有任何解决方法?

Sto*_*ica 16

如果你查看最新的C++ 1z草案的修订摘要,你会在[diff.cpp14.dcl.dcl]中看到这一点.

[dcl.stc]
更改:删除寄存器存储类说明符.
基本原理:在本国际标准的未来版本中启用已弃用关键字的重新调整用途.
对原始特征的影响:使用寄存器存储类说明符的有效C++ 2014声明在本国际标准中不正确.可以简单地删除说明符以保留原始含义.

警告可能是由于此.


Cur*_*ous 13

register不再是存储类说明符,您应该将其删除.编译器可能没有发出正确的错误或警告,但您的代码不应该register开始

以下是标准的引用,告知人们他们应该register在他们的代码中做些什么(相关部分强调),你可能有一个旧版本的文件

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

更改:在C++中,register不是存储类说明符.

基本原理:存储类说明符对C++没有影响.对原始特征的影响:删除语义明确定义的特征.

转换难度:句法转换.

如何广泛使用:普通.

  • 你没有,@ Venemo.您无法告诉编译器*非常长时间.没有大的损失; 优化器可以做出比寄存器分配更好的决策.编译器简单地忽略了`register`存储类说明符,只要有明显的含义.它意味着如果你试图获取如此声明的变量的地址,编译器会产生错误. (10认同)

小智 6

您的担心是没有根据的,因为有问题的文件实际上并不包含register关键字:

grep "register" /usr/include/linux/rtnetlink.h
Run Code Online (Sandbox Code Playgroud)

没有输出.无论哪种方式,您都不应该收到警告,因为:

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

  • 尝试在C++模式下编译属于系统项目的文件(如Linux内核)是不明智的,因为可能存在微妙且令人讨厌的重大变化

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