在编译的哪个阶段保留标识符?

Jon*_*rdy 1 c c++ compiler-construction reserved-words

在这里工作只是一点点好奇心.在处理危险的事情时,我开始考虑各种编译器及其相关标准库的实现.这是我思想的进展:

  1. 某些类标识符保留用于C++和C中的实现.

  2. 编译器必须执行编译阶段(预处理,编译,链接),就好像它们是按顺序执行一样.

  3. C预处理器不知道标识符的保留状态.

  4. 因此,当且仅当以下情况时,程序可以使用保留标识符:

    1. 使用的保留标识符是所有预处理器符号.

    2. 预处理结果不包括保留标识符.

    3. 标识符不与编译器预定义的符号冲突(GNUC等人).

这有效吗?我对第3点和第4.3点不确定.此外,有没有办法测试它?

Joh*_*all 5

(关于这个问题的评论解释说我们在谈论C99第7.1.3节中的保留标识符,即在/^_[A-Z_]/任何地方,/^_/在文件范围内,/^str[a-z]/与外部链接等匹配的标识符.所以这是我至少在一部分的猜测你在问什么...)

它们不是保留在编译器(任何特定阶段)预期诊断其滥用的意义上.相反,它们是保留的,如果你自己愚蠢地(误)使用它们,如果你的程序停止工作或者在以后停止编译,你就不会抱怨.

我们都看到当只有大量知识的人看到系统头部然后编写他们自己的头部防护时会发生什么:

#ifndef _MYHEADER_H
#define _MYHEADER_H
// ...
#endif
Run Code Online (Sandbox Code Playgroud)

他们正在调用未定义的行为,但没有任何事情将其诊断为" 错误:最终用户代码使用的保留标识符 ".相反,他们很幸运,一切都很好; 但有时它们会与实施所关注的标识符相冲突,并且会发生令人困惑的事情.

同样,我经常有一个名为ex的外部可见函数strip():

char *strip(char *s) {
  // remove leading whitespace
  }
Run Code Online (Sandbox Code Playgroud)

通过阅读C99的7.1.3,7.26和7.26.11,这将调用未定义的行为.但是我决定不关心这个.标识符不是保留的,因为预计今天会发生任何不良事件,但因为标准保留了自己str-ip()在未来版本中发明新标准例程的权利.而且我已经决定了我认为字符串 - ip无论可能是什么,对于将来添加的字符串操作来说是一个不太可能的名字 - 所以在不太可能发生的情况下,当我到达时,我将穿过那座桥它.从技术上讲,我正在调用未定义的行为,但我不希望被咬.

最后,反对你的观点4:

#include <string.h>
#define memcpy(d,s,n)  (my_crazy_function((n), (s)))
void foo(char *a, char *b) {
  memcpy(a, b, 5);  // intends to invoke my_crazy_function
  memmove(a, b, 5); // standard behaviour expected
}
Run Code Online (Sandbox Code Playgroud)

这符合你的4.1,4.2,4.3(如果我理解你对最后一个的意图).但是,如果memmove另外实现为以(根据7.1.4/1)编写的宏memcpy,那么您将遇到麻烦.