标准库实现中双下划线的原因
Reasons four double undescores in standard library implementations
标准库(C 或 C++)的实现是否有任何技术原因,IMO 滥用,下划线的方式(=用两个下划线前缀所有内容 + 添加尾随下划线以表示变量是成员变量)?
我知道 /.*__.*/
和 /_[A-Z].*/
(<= 正则表达式)是按实现保留的。但这不应该是指编译器的实现而不是(标准)库吗?
标准库在选择内部名称方面不能像其他任何库一样吗?
标准库以两个下划线开头的内部名称是有充分理由的:这些名称是为实现保留的。
假设您编写了以下代码:
#include <iostream>
using namespace std;
long square(long x)
{
return x*x;
}
int main()
{
cout << square(3) << endl;
}
我想如果这最终调用了一些用于实现标准库的内部函数 square(int)
并做了一些完全不同的事情,你会不高兴,因为它比你的 square(long)
更匹配square(3)
.
通过在所有内部名称前加上双下划线前缀,同时标准声明不允许您这样做,标准库作者确保不会发生这样的事情。
现在您可能会说 <iostream>
不是 STL 的一部分,但是每个标准库头文件都可能包含任何其他标准库头文件,因此 iostream
很可能包含一个 STL 头文件用于它的实现。
即使在外部看不到的本地标识符的情况下,带有双下划线的标识符也有意义的另一个原因是您可能已经定义了一个同名的宏。考虑:
#define value 15
#include <iostream>
int main()
{
std::cout << value;
}
这是合法的代码,当然应该输出 15。但是现在想象一下如果 iostream
中的某个对象声明了一个局部变量名称 value
会发生什么。您的代码显然无法编译。
请注意,标准库是实现的一部分(毕竟它在 C++ 标准中有所描述),因此它可以随心所欲地使用保留名称。
标准库(C 或 C++)的实现是否有任何技术原因,IMO 滥用,下划线的方式(=用两个下划线前缀所有内容 + 添加尾随下划线以表示变量是成员变量)?
我知道 /.*__.*/
和 /_[A-Z].*/
(<= 正则表达式)是按实现保留的。但这不应该是指编译器的实现而不是(标准)库吗?
标准库在选择内部名称方面不能像其他任何库一样吗?
标准库以两个下划线开头的内部名称是有充分理由的:这些名称是为实现保留的。
假设您编写了以下代码:
#include <iostream>
using namespace std;
long square(long x)
{
return x*x;
}
int main()
{
cout << square(3) << endl;
}
我想如果这最终调用了一些用于实现标准库的内部函数 square(int)
并做了一些完全不同的事情,你会不高兴,因为它比你的 square(long)
更匹配square(3)
.
通过在所有内部名称前加上双下划线前缀,同时标准声明不允许您这样做,标准库作者确保不会发生这样的事情。
现在您可能会说 <iostream>
不是 STL 的一部分,但是每个标准库头文件都可能包含任何其他标准库头文件,因此 iostream
很可能包含一个 STL 头文件用于它的实现。
即使在外部看不到的本地标识符的情况下,带有双下划线的标识符也有意义的另一个原因是您可能已经定义了一个同名的宏。考虑:
#define value 15
#include <iostream>
int main()
{
std::cout << value;
}
这是合法的代码,当然应该输出 15。但是现在想象一下如果 iostream
中的某个对象声明了一个局部变量名称 value
会发生什么。您的代码显然无法编译。
请注意,标准库是实现的一部分(毕竟它在 C++ 标准中有所描述),因此它可以随心所欲地使用保留名称。