在阅读Herb Sutter撰写的关键词(或其他名称)时,我遇到了以下几点:
没错,有些关键字在语义上等同于空格,这是一个美化的评论.
和
我们已经看到为什么C++语言将关键字视为保留字,我们已经看到两个关键字-auto和register--它们对C++程序没有任何语义差异.不要使用它们; 无论如何,它们只是空格,并且有更快的方式来输入空格.
如果关键字auto(可能不是在C++ 11中)并且register没有价值,那么它们为什么被创建和使用?
如果包含register变量之前没有任何区别
#include<stdio.h>
int main(){
register int a = 15;
printf("%d\n%d\n",&a,a);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为什么上述程序会出错?
test_register.c:在函数'main'中:
test_register.c:4:2:错误:请求的寄存器变量'a'的地址
的printf( "%d \n%d \n",&A,A);
以下程序适用于C++.
#include<iostream>
int main(){
register int a = 15;
std::cout<<&a<<'\n'<<a;
return 0;
}
Run Code Online (Sandbox Code Playgroud) 从语法的角度来看,我已经看过"volatile"关键字在C++函数中有多少用法?关于在函数上使用volatile关键字,但没有明确解释该问题的案例1做了什么.只有一位受访者表示这似乎毫无意义/无用.
然而,我不能完全接受这种说法,因为GNUC的AES软件实现已经使用了几年,它们有许多这样的功能:
INLINE volatile void functionname( /* ... */ ) {
/* ... */
asm( /* ... */ ) // embedded assembly statements
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
必须有这种用法的原因.谁能:
一.告诉我原来的原因是什么; 和
乙.现在如何达到理想的效果?
我正在使用Ubuntu和GCC 4.6.3.
void fatal( /* ... */ ) { /* ... */ exit(1); }
typedef void voidfn ();
volatile voidfn fatal;
Run Code Online (Sandbox Code Playgroud)
这将允许编译器识别'致命'不会返回.
但是这种情况似乎不适用于AES代码.自从我在集会上做了很多事以来,已经有很长一段时间了,但我想我会认识到跳跃或类似的事情.
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++中使用/重新定义这些宏,是否有任何解决方法?
最近我在一次采访中被问到全局寄存器变量.我搞砸了说任何全局变量都将存储在数据段中.但后来我被问及GCC.在采访后我得出结论gcc支持全局寄存器变量.
#include<stdio.h>
register int var asm("ebx"); //storing global variable in register explicitly
int main(void)
{
.......
}
Run Code Online (Sandbox Code Playgroud)
这是链接 https://gcc.gnu.org/onlinedocs/gcc/Global-Reg-Vars.html#Global-Reg-Vars
但现在我对它的生命周期和范围感到困惑,它是否会作为普通的全局变量或寄存器变量工作?gcc上还有任何方法或命令,以便我们确保编译器不会简单地忽略register关键字并将存储在实际的寄存器中吗?
最新版本的python 2.7(2.7.13)包含一个unicodeobject.h使用该register关键字的标头.我的理解是C++ 17 删除了这个关键字.使用C++ 17编译此头文件时,会触发一系列警告,包括:
/opt/anaconda/include/python2.7/unicodeobject.h:534:24: warning: ISO C++1z does not allow ‘register’ storage class specifier [-Wregister]
register PyObject *obj, /* Object */
^~~
/opt/anaconda/include/python2.7/unicodeobject.h:553:24: warning: ISO C++1z does not allow ‘register’ storage class specifier [-Wregister]
register PyObject *obj /* Object */
^~~
/opt/anaconda/include/python2.7/unicodeobject.h:575:29: warning: ISO C++1z does not allow ‘register’ storage class specifier [-Wregister]
register const wchar_t *w, /* wchar_t buffer */
^
/opt/anaconda/include/python2.7/unicodeobject.h:593:23: warning: ISO C++1z does not allow ‘register’ storage class specifier …Run Code Online (Sandbox Code Playgroud) 如果__SHA__未定义,我们使用内联汇编使SHA指令可用.在GCC下我们使用:
GCC_INLINE __m128i GCC_INLINE_ATTRIB
MM_SHA256RNDS2_EPU32(__m128i a, const __m128i b, const __m128i c)
{
asm ("sha256rnds2 %2, %1, %0" : "+x"(a) : "xm"(b), "Yz" (c));
return a;
}
Run Code Online (Sandbox Code Playgroud)
Clang不遵守 GCC的Yz约束条款(参见Clang 3.2 Issue 13199和Clang 3.9 Issue 32727),该sha256rnds2指令要求:
Run Code Online (Sandbox Code Playgroud)Yz First SSE register (%xmm0).
我们mov为Clang 添加了一个:
asm ("mov %2, %%xmm0; sha256rnds2 %%xmm0, %1, %0" : "+x"(a) : "xm"(b), "x" (c) : "xmm0");
Run Code Online (Sandbox Code Playgroud)
性能每字节约3个周期.在我的2.2 GHz Celeron J3455测试机(带有SHA扩展的Goldmont)上,大约为230 MiB/s.它不平凡.
看看反汇编,k当执行两轮时,Clang没有围绕SHA …
我正在读这篇文章,它说该register关键字很可能会从下一个C++标准中删除.它还说register2011年已被弃用.那么,register存储类说明符有什么问题?
我认为现代编译器非常智能,它们隐式优化常用变量以实现速度(快速访问)并将它们放入CPU寄存器中.
但是,C++专家也说不要或从不使用register.因此,register关键字的问题是什么?
引自"Thinking in c ++"一书关于寄存器变量的部分:"寄存器变量的使用存在限制.你不能获取或计算寄存器变量的地址.一个寄存器变量只能在一个块中声明(你不能有全局或静态寄存器变量.)"
所以我写了这段程序来测试:
int global = 2;
// error
// register int global2 = 3;
int main() {
register int local2 = 2;
cout << local2 << " " << &local2 << endl;
}
Run Code Online (Sandbox Code Playgroud)
但是g ++没有生成错误,打印出local2的地址.那么为什么我可以在没有错误的情况下获取地址?
考虑到数值计算,在我看来,寄存器存储类(目前已弃用并从标准中删除)是一个很好的优化提示。是否有任何具体原因将其从标准中明确删除?