首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >翻译阶段4的非保留标识符是否使得无法在翻译阶段7保留文件范围标识符?

翻译阶段4的非保留标识符是否使得无法在翻译阶段7保留文件范围标识符?
EN

Stack Overflow用户
提问于 2022-07-24 21:43:58
回答 3查看 69关注 0票数 2

请考虑以下代码:

代码语言:javascript
复制
/* 
 * stdio.h
 * 
 * note: it is an example of a particular implementation of stdio.h
 * containing _x; it is not "my code added to stdio.h"
 */
void _x(void);

/* t627.c */
#define _x 0
#include <stdio.h>

调用:

代码语言:javascript
复制
$ gcc t627.c

t627.c:1:12: error: expected identifier or ‘(’ before numeric constant
    1 | #define _x 0
      |            ^
stdio.h:1:6: note: in expansion of macro ‘_x’
    1 | void _x(void);

在翻译阶段4,标识符_x是非保留的.在翻译阶段7,保留标识符_x (用于普通和标记名称空间中具有文件范围的标识符)。由于翻译阶段4先于翻译阶段7,那么在翻译阶段7,标识符_x (当前定义为宏名称)已经被替换列表0所取代,从而使程序无效。

这是否意味着当用户定义的宏(以下划线开头,后面跟着小写字母)与同名的文件范围标识符发生冲突/重叠时,不能保留该文件范围标识符?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2022-07-24 23:29:45

找到P.J. Plauger的相关引文(重点是后加的):

请记住,用户可以编写以下划线开头的宏,然后是小写字母。这些名称将保留的与实现者重叠,以命名外部函数和数据对象。

因此,答案似乎是“是”。

票数 0
EN

Stack Overflow用户

发布于 2022-07-24 22:05:49

#define宏始终是文本替代。

当然,头文件本身并不是编译好的实体,因此只有在它们是#included时才会对其进行评估。

假设您有一个包含某个非宏标识符*的标头。

在C模块中,您可以将相同的标识符扩展为任意和病态的标识符,然后将头扩展为#define #include

由于编译器在遇到#define之前遇到了#include,所以冲突标识符头中的所有提及都将被宏的展开所替代。其后果可能是(而且常常是)灾难性的,或者至少很难调试。

标识符是否以下划线开头并不重要。例如,如果您编写#define printf scanf,就会导致混乱!

(*我规定“非宏”只是为了避免如果头重新定义(或试图重新定义)首先定义的宏时会发生的复杂情况。)

票数 2
EN

Stack Overflow用户

发布于 2022-07-25 01:56:40

不允许使用任何保留名称定义宏。这在C标准第7.1.3p2节中有明确的说明。

如果程序在保留标识符的上下文中声明或定义标识符(7.1.4允许的除外)、或将保留标识符定义为宏名称,则行为未定义。

(粗体:我的重点。)

换句话说,在某些阶段-7上下文中保留的每个标识符也保留为宏名称。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73102269

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档