在C中,register
存储限定符是实现的提示,应尽可能快地访问此标识符(例如存储在CPU寄存器中)。
§6.7.1 具有存储类说明符寄存器的对象的标识符声明表明对对象的访问尽可能快。这些建议有效的程度是实施定义的。
和
§6.7.3限制限定符的预期用途(如寄存器存储 class)是为了促进优化[...]
但是,我听说过register
具有更强意义的实现(特别是嵌入式系统中的实现):它是命令,编译器应将限定标识符放在注册
那么,是一个实现允许来遵循这种行为,因此被认为是符合标准的?什么会允许这样做?
我提出这个问题是因为我发现有必要将该物品放入登记簿中,这不再是标准规定的建议;换句话说,他们发生冲突。
答案 0 :(得分:3)
只要它不能阻止格式良好的程序以任何方式编译或影响标准中规定的观察行为,就可以这样做。
标准已禁止使用register
说明符声明对象的地址或对齐方式,因此该部分不会成为问题。如果您使用register
声明的对象多于可用的寄存器,则会出现更棘手的情况。除非实现仍然允许溢出register
对象(暂时将值从寄存器移动到例如堆栈,然后返回),否则这将是实现无法编译符合的程序的情况。符合标准。
答案 1 :(得分:2)
正如你所说,标准说“这些建议有效的程度是实施定义的。”
这使得实施自由范围可以做任何事情,从忽视建议到移动天地来实现它。选择接受register
说明符要求使用寄存器的实现肯定不会与标准相矛盾,也不是一种只关于寄存器放置而不管说明符做出自己决定的实现。
实现不应该做的一件事是拒绝编译程序,因为它需要溢出register
- 至少,达到§5.2.4.1翻译限制中指定的限制< / em> - 但没有什么能阻止编译器发出警告。 (没有什么能阻止编译器发出关于任何事情的警告;编译器通常会警告那些被认为是危险的完全合法的构造。)
编辑:重读5.2.4.1,在我看来,实现实际上可以拒绝编译一个它认为有太多register
说明符的程序,因为只有限制条款绑定实现以便能够翻译和执行“一个程序”,其中包括(例如)“在一个块中声明的块范围的511个标识符”,而不是任何这样做的程序。因此,据我所见,编译器可能会坚持认为达到该限制的“至少一个程序”没有任何register
规范。
注意:并非所有CPU都具有常识中的寄存器,但标准实际上并未说明任何有关硬件的信息。它只是说register
说明符传达了程序员希望“尽可能快地访问对象”的愿望。而且,编译器满足该期望的尝试实际上不必优化对象的访问;它不会违反优化尝试未能优化的标准。