C90 - C99: 寄存器结构体

3
“register struct”是否合法?从标准的角度和(与标准分离)在Gcc中是如何处理的?
3个回答

3

是的。(没有引用,只是没有禁止这样做。有一个注释认为使用寄存器和数组是有效的,在C语言中,数组比结构体更像是一个二等公民。)


3

是的,它是合法的,但由于寄存器仅是编译器提示可能尝试的内容,因此任何实现都不必听取它。而且很容易创建一个无法存储在分配的寄存器空间内的结构。

一旦你开始接近与机器相关的问题,它们在标准中的作用往往只是建议,因为硬件变化很大,因此在所有体系结构中都不可靠地实现相同的功能。


2

是的,它是有效的。

register 作为关键字并不意味着变量将保存在寄存器中。(在C语言中基本上没有这个概念)。它只是表示不要获取该变量的地址


很遗憾register会强制执行约束违规,否则它将更有用,因为关键字的意思是“在两次访问之间,除非取地址,否则此lvalue的值不会改变。”。例如register x,y; getCoords(&x,&y);,编译器必须在调用getCoords期间将xy存储在内存中,但可以在之后的寄存器中缓存它们。这对于优化很有用,并且编译器可能无法自行解决。太糟糕了,标准会考虑到这一点... - supercat
违反约束。 - supercat
@supercat,这真是旧事一则。不,就像你所说的那样,这种优化最好留给编译器来处理。register只是一个表示“我不希望这个变量被别名化”的标记,与const限定符结合使用时可以非常有用。 - Jens Gustedt
目前的情况是,register 是否表明了一个多遍编译器不能轻易地自己找出来的东西?相比之下,编译器有没有办法找出,当一个对象的地址已经暴露给外部世界时,可以安全地跨越函数调用寄存器缓存它?基本上,我的意思是一个对象永远不会被别名化,除了某些狭窄而容易识别的上下文。这个指令的作用类似于 restrict,但适用于大多数直接访问而不是通过指针访问的事物。 - supercat
适当使用register限定符(如所述),以及restrict,将为编译器提供所需的信息,即使在-fno-strict-aliasing模式下也可以执行大多数有用的别名优化(包括许多目前即使使用-fstrict-aliasing也不可能实现的优化)。顺便说一句,register目前也是全局变量的约束违规,但应用相同的语义也将允许不可能的优化,例如在访问int*时保持全局register int foo;缓存在寄存器中。是否有任何现有方法允许这样做? - supercat
当前的寄存器类似于限制符。从有效代码中删除它不会改变语义。添加它可能会使代码无效,因此指向一个错过某些优化的点。但像这样的旧问题可能不是讨论这个问题的合适场所。 - Jens Gustedt

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接