【问题标题】:Clash with identifier 'clock' from time.h与 time.h 中的标识符“时钟”发生冲突
【发布时间】:2016-10-04 12:37:13
【问题描述】:

下面的程序

#include <ctime>

struct clock {};

int main() {
    clock c;
}

无法在 g++ 5.4 和 clang 3.8(Ubuntu 64 位)上编译。

g++ 输出

clock.cpp: In function ‘int main()’:
clock.cpp:6:11: error: expected ‘;’ before ‘c’
    clock c;
          ^

叮当声输出

clock.cpp:6:5: error: must use 'struct' tag to refer to type 'clock' in this scope
    clock c;
    ^
    struct 
/usr/include/time.h:189:16: note: struct 'clock' is hidden by a non-type declaration of 'clock' here
extern clock_t clock (void) __THROW;
               ^
1 error generated.

诊断的形式略有不同,但与同一问题相关。与标准 C 函数 clock 和程序中定义的同名结构存在冲突。来自time.h的相关声明:

extern clock_t clock (void) __THROW;

问题是:由于程序包含&lt;ctime&gt;,这些符号不应该在std 命名空间中吗?有趣的是,这个声明位于一个宏之后的几行,它读取为__BEGIN_NAMESPACE_STD。另外,在&lt;ctime&gt;,可以看到:

namespace std
{
    using ::clock_t;
    using ::time_t;
    using ::tm;

    using ::clock;
    ...
}

这里有什么错误吗?

谢谢。

【问题讨论】:

    标签: c++ g++ clang


    【解决方案1】:

    问题是:这些符号不应该在std 命名空间中吗...

    是的,他们是。不幸的是,C++ 标准还允许实现将来自 C 库派生头文件的名称放在全局命名空间中。在这种情况下,您会得到std::clock ::clock

    这适用于所有 &lt;c*&gt; C++ 标头,在 C 中具有相应的 &lt;*.h&gt; 版本。

    【讨论】:

    • 你说得对,这很不幸。我会以 C 兼容性 的名义将其添加到 C++ 程序员必须忍受的不便列表中。您认为有希望更改标准以要求这些符号 onlystd 命名空间中可用吗?谢谢。
    • @Zunino - 不,这不会发生。这在过去是必需的,但没有人以这种方式实现它:维护太多。允许在全局命名空间中使用 C 名称的更改反映了现实。将clock 放入您自己的命名空间中。
    • @PeteBecker 好吧,这太糟糕了。我可能在这里遗漏了一些东西,但为什么不能更明确一些,例如:如果你想在全局命名空间中有符号,请使用 C 头文件;如果您想将它们整齐地放在std 中,请使用 C++ 对应项。然后用户会得到他们想要的东西。在目前的状态下,它不仅混乱而且具有误导性。如果用户决定包含&lt;map&gt;(可能间接包含time.h),则无意中使用clock 等符号的C++ 程序可能会突然中断。它看起来不正确。谢谢。
    • @Zunino - 再次将clock 放入您的命名空间。这就是命名空间的用途。
    • @PeteBecker 对。在示例程序中的标识符前面加上struct 似乎也是另一种解决方法。然而,我的观点不是关于如何解决问题,而是关于这种情况和其他类似情况如何使新的(而不是那么新的)C++ 程序员感到困惑和赶走。 Stroustrup 本人长期以来一直主张消除语言的不一致和不必要的复杂性,目的是使其对新手更加友好,我认为这是一个崇高的目标。免责声明:我并不是在暗示您不同意;我只是想尝试解释一下我的观点。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-25
    • 1970-01-01
    • 2012-09-26
    • 2013-11-26
    • 1970-01-01
    相关资源
    最近更新 更多