C 标准库中的符号是否保留在 C++ 中?

Are symbols from the C standard library reserved in 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;
}

Where does the C++ standard forbids to use freely symbols from the C standard library

最新草稿:

[extern.names]

Each name from the C standard library declared with external linkage is reserved to the implementation for use as a name with extern "C" linkage, both in namespace std and in the global namespace.

Each function signature from the C standard library declared with external linkage is reserved to the implementation for use as a function signature with both extern "C" and extern "C++" linkage, or as a name of namespace scope in the global namespace.


when they are not explicitely included in a compilation unit?

如果您完全使用标准库,则标准库的所有名称保留均有效。

如果您包含任何标准 header(或者任何 header,其确切内容您无法控制,因此可能包含标准 header),那么您可能会间接包括其他标准 headers,包括从 C.

继承的那些

[extern.names]

3 Each name from the C standard library declared with external linkage is reserved to the implementation for use as a name with extern "C" linkage, both in namespace std and in the global namespace.

注意本段保留名称本身。因此在全局命名空间中使用别名 time 违反了此约定。