c++ - C 标准库中的符号是否保留在 C++ 中?
问题描述
这是对另一个问题的跟进。
最初的问题还有其他问题,但我不得不意识到主要问题(根据 CLang)是重新定义time
为不同的符号,而只使用了不错的C++ 包含。
所以这是一个精简的版本:
#include<iostream>
using std::cout;
using std::endl;
class time
{
public:
int h, min, sec;
};
const int full = 60;
void canonify(time& pre) // Error here (line 14)
{
pre.min += pre.sec / full;
pre.h += pre.min / full;
pre.sec %= full;
pre.min %= full;
}
int main()
{
time a; // and here (line 23)
a.h = 3;
a.min = 128;
a.sec = 70;
canonify(a);
cout << a.h << ":" << a.min << ":" << a.sec << endl;
}
当然,用time
不同的符号替换或使用struct time
就足以解决问题。换句话说,我的问题不是如何使代码运行,而只是我们是否必须将 C 库中的符号视为C++ 中的保留标记。Clang 11(在 MSVC19 上)阻塞:
1>ess.cpp(14,15): error : must use 'class' tag to refer to type 'time' in this scope
1>...\ucrt\time.h(518,42): message : class 'time' is hidden by a non-type declaration of 'time' here
1>ess.cpp(23,5): error : must use 'class' tag to refer to type 'time' in this scope
1>...\ucrt\time.h(518,42): message : class 'time' is hidden by a non-type declaration of 'time' here
所以问题是:当 C 标准库中的符号没有明确包含在编译单元中时,C++ 标准在哪里禁止自由使用它们?
有趣的是,相同的代码(一旦翻译......)在 C 中可以正常工作:
#include <stdio.h>
//
typedef struct
{
int h, min, sec;
}time;
//
const int full = 60;
//
void canonify(time* pre)
{
pre->min += pre->sec / full;
pre->h += pre->min / full;
pre->sec %= full;
pre->min %= full;
}
int main()
{
time a;
a.h = 3;
a.min = 128;
a.sec = 70;
canonify(&a);
printf("%d:%d:%d\n", a.h, a.min, a.sec);
return 0;
}
解决方案
[extern.names]
3使用外部链接声明的 C 标准库中的每个名称都保留给实现,以用作具有外部“C”链接的名称,无论是在命名空间 std 中还是在全局命名空间中。
请注意,本段保留名称本身。因此,全局命名空间中的别名time
违反了这个约定。
推荐阅读
- php - 在 PHP 中的一行中创建、执行和使用函数
- python - 如何获取索引的值?
- java - JSONObject/SharedPreferences 无法检索字符串
- jmeter - JMeter JMS点对点采样器不带参数
- node.js - 猫鼬聚合匹配不适用于正则表达式
- javascript - onclick 单选按钮显示/隐藏内容
- php - 强制根 url 在视图中
- php - 无法在 macOS 本地安装/更新插件 wordpress
- ms-access - Pipedrive:PUT从vba更新过滤器?
- javascript - Vue.use(plugin) 导致错误:Vue 是一个构造函数,应该使用 `new` 关键字调用