在编译的哪个阶段保留保留标识符? [英] At what stage of compilation are reserved identifiers reserved?

查看:138
本文介绍了在编译的哪个阶段保留保留标识符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在这里,只是有点好奇.在处理一些危险的事情时,我不得不考虑各种编译器及其相关标准库的实现.这是我思想的发展:

Just a little curiosity at work, here. While working on something dangerous, I got to thinking about the implementations of various compilers and their associated standard libraries. Here's the progression of my thoughts:

  1. 某些标识符类别已保留,供在C ++和C中实现.

  1. Some classes of identifiers are reserved for implementation use in C++ and C.

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

A compiler must perform the stages of compilation (preprocessing, compilation, linking) as though they were performed in sequence.

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

The C preprocessor is not aware of the reserved status of identifiers.

因此,程序仅在以下情况下可以使用保留的标识符 :

Therefore, a program may use reserved identifiers if and only if:

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

  1. The reserved identifiers used are all preprocessor symbols.

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

The preprocessing result does not include reserved identifiers.

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

The identifiers do not conflict with symbols predefined by the compiler (GNUC et. al.)

这有效吗?我不确定第3点和第4.3点.而且,有没有一种测试方法?

Is this valid? I'm uncertain on points 3 and 4.3. Moreover, is there a way to test it?

推荐答案

(关于该问题的评论说明,我们从C99第7.1.3节的意义上说是在保留的标识符,即,与任何地方的/^_[A-Z_]/匹配的标识符,文件范围内的/^_/,具有外部链接的/^str[a-z]/等等.因此,我的猜测至少是您要问的内容的一部分...)

(The comments on the question explain that we're talking about reserved identifiers in the sense of C99 section 7.1.3, i.e., identifiers matching /^_[A-Z_]/ anywhere, /^_/ in file scope, /^str[a-z]/ with external linkage, etc. So here's my guess at at least a part of what you're asking...)

从保留编译器(在任何特定阶段)可以诊断其滥用的意义上说,它们不是保留的.相反,它们是保留的,如果您愚蠢到自己(滥用)它们,就不会抱怨程序停止运行或以后不再编译.

They're not reserved in the sense that (any particular phase of) the compiler is expected to diagnose their misuse. Rather, they're reserved in that if you're foolish enough to (mis)use them yourself, you don't get to complain if your program stops working or stops compiling at a later date.

我们都已经看到,只有很少知识的人们查看系统标题后,然后编写自己的标题防护,将会发生什么事情:

We've all seen what happens when people with only a dangerous amount of knowledge look inside system headers and then write their own header guards:

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

他们正在调用未定义的行为,但是没有任何东西可以将其诊断为"错误:最终用户代码使用的保留标识符".相反,大多数情况下他们很幸运,而且一切都很好.但是有时它们会与实现中感兴趣的标识符发生冲突,并且会发生混乱的情况.

They're invoking undefined behaviour, but nothing diagnoses this as "error: reserved identifier used by end-user code". Instead mostly they're lucky and all is well; but occasionally they collide with an identifier of interest to the implementation, and confusing things happen.

类似地,我经常有一个名为strip()的外部可见函数:

Similarly, I often have an externally-visible function named strip() or so:

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

通过阅读C99的7.1.3、7.26和7.26.11,将调用未定义的行为.但是,我决定不关心这一点.保留标识符并不意味着将来会发生任何不良情况,而是因为标准保留了在将来的修订版中发明新的标准str-ip()例程的权利.而且我决定我认为 string -ip可能是将来在字符串操作中添加的不太可能的名字-因此,在不太可能发生的情况下,当我到达那座桥时,我会过桥.从技术上讲,我正在调用不确定的行为,但我不希望被咬.

By my reading of C99's 7.1.3, 7.26, and 7.26.11, this invokes undefined behaviour. However I have decided not to care about this. The identifier is not reserved in that anything bad is expected to happen today, but because the Standard reserves to itself the right to invent a new standard str-ip() routine in a future revision. And I've decided that I reckon string-ip, whatever that might be, is an unlikely name for a string operation to be added in the future -- so in the unlikely event that happens, I'll cross that bridge when I get to it. Technically I'm invoking undefined behaviour, but I don't expect to get bitten.

最后,是第4点的反例:

Finally, a counter-example to your point 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另外被实现为根据memcpy编写的宏(通过7.1.4/1),那么您将遇到麻烦.

This complies with your 4.1, 4.2, 4.3 (if I understand your intention on that last one). However, if memmove is additionally implemented as a macro (via 7.1.4/1) that is written in terms of memcpy, then you're going to be in trouble.

这篇关于在编译的哪个阶段保留保留标识符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆