据我所知,根据C标准,只有两个register
的属性是必需的:不能接受地址,也不能与_Alignas
一起使用.因此,您的编译器must对如下代码发出诊断:
register int foo;
&foo; // constraint violation
register int bar[3]; // basically useless but not an error by itself
bar; // constraint violation, decays to pointer
bar[1]; // likewise
register _Alignas(16) int baz; // constraint violation
(顺便说一句,GCC实际上允许在没有诊断的情况下使用register int bar[3]; bar[1];
;但除非您使用-pedantic
,否则它不会声称是符合要求的C实现,在这种情况下,您确实会收到应该得到的警告.)
请注意,"诊断"不一定是错误;警告就足够了.因此,对于上面的代码片段,如果您愿意,可以发出警告,然后继续以任何您想要的方式处理它们(例如,忽略register
声明).
当然,由于它是一个关键字,如果它出现在语法上不允许的地方,例如作为标识符,您必须发出诊断.
int register;
void register(void);
其他一切都由您作为实施者自行决定.如果您愿意,您可以完全忽略它,而且在很大程度上,这就是现代编译器所做的.
该标准对register
的本意是"建议
传统上,这可能在寄存器分配过程中使用.如果您处于机器寄存器用完的情况下,需要将一些变量溢出到内存中,那么您可能会优先考虑register
个变量,并try 首先溢出非register
个变量.例如,如果您有
int a,b,c,d,e,f,g,h;
register int r;
那么,如果可能的话,您可能更愿意将a,...,h
中的任何一个或全部溢出,而不是r
.
对于20世纪70年代或80年代的编译器来说,这是合理的.另一方面,现代优化编译器将拥有复杂的启发式算法来决定如何分配寄存器,在许多情况下,这些启发式算法比程序员的假设更准确.因此,现代编译器更有可能完全依赖自己的算法,而忽略register
提示.
The "entry in a symbol table" remark might be from the same source (Expert C Programming - Deep C Secrets) as mentioned in Why is the 'auto' keyword useful for compiler writers in C?. It is not very clearly worded. The only sense I can make of it is that the compiler does need to keep track of which storage class specifiers were used to declare an object, e.g. to issue required diagnostics as noted above. So whatever data structure you use to associate the name and type of an object will need to have a flag to indicate if it was declared register
, and that may be what they mean by "symbol table".