gpt4 book ai didi

c++ - 保留标识符在编译的哪个阶段被保留?

转载 作者:塔克拉玛干 更新时间:2023-11-03 08:24:03 27 4
gpt4 key购买 nike

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

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

  2. 编译器必须按顺序执行编译阶段(预处理、编译、链接)。

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

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

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

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

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

这有效吗?我不确定第 3 点和第 4.3 点。另外,有没有办法测试呢?

最佳答案

(对该问题的评论解释说,我们正在讨论 C99 第 7.1.3 节意义上的保留标识符,即匹配 /^_[A-Z_] 的标识符/ 任何地方,/^_/ 在文件范围内,/^str[a-z]/ 带有外部链接,等等。所以这是我的猜测至少你问的一部分......)

在预期编译器(的任何特定阶段)诊断其误用的意义上,它们不是保留的。相反,它们是保留的,因为如果您愚蠢到自己(误)使用它们,那么如果您的程序停止工作或稍后停止编译,您就不会提示。

我们都已经看到,当只有危险的知识量的人查看系统 header 内部然后编写他们自己的 header 保护时会发生什么:

#ifndef _MYHEADER_H
#define _MYHEADER_H
// ...
#endif

他们正在调用未定义的行为,但没有人将此诊断为“错误:最终用户代码使用的保留标识符”。相反,他们大多很幸运,一切都很好;但偶尔它们会与实现感兴趣的标识符发生冲突,并且会发生令人困惑的事情。

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

char *strip(char *s) {
// remove leading whitespace
}

根据我对 C99 的 7.1.3、7.26 和 7.26.11 的阅读,这会调用未定义的行为。但是我决定不关心这个。标识符不是保留的,因为今天预计会发生任何不好的事情,而是因为标准保留在未来修订中发明新标准 str-ip() 例程的权利。而且我已经决定我认为 string-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
}

这符合您的 4.1、4.2、4.3(如果我理解您对最后一个的意图)。但是,如果 memmove 被另外实现为一个宏(通过 7.1.4/1),它是根据 memcpy 编写的,那么您就会有麻烦了。

关于c++ - 保留标识符在编译的哪个阶段被保留?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3816345/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com