C++重新定义变量,全局命名空间被污染了,我不知道为什么

ali*_*iak 6 c++ macos compilation clang c++11

所以我觉得我做了一些非常愚蠢的事情,我无法弄清楚这一点.以下程序给我带来了很多痛苦:

#include <iostream>
int time = 0;
int main(int argc, char **argv) {
    std::cout << "hi" << std::endl;
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

我的编译字符串是:clang++ -std=c++1y --verbose -stdlib=libc++ main.cpp -o main.重定义错误是,/usr/include/time.h:116:8: note: previous definition is here并将此--verbose显示为包含路径顺序:

Apple LLVM version 6.0 (clang-600.0.56) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin14.1.0
Thread model: posix
 "/Library/Developer/CommandLineTools/usr/bin/clang" -cc1 -triple x86_64-apple-macosx10.10.0 -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -main-file-name main.cpp -mrelocation-model pic -pic-level 2 -mdisable-fp-elim -masm-verbose -munwind-tables -target-cpu core2 -target-linker-version 241.9 -v -resource-dir /Library/Developer/CommandLineTools/usr/bin/../lib/clang/6.0 -stdlib=libc++ -std=c++1y -fdeprecated-macro -fdebug-compilation-dir /Users/aliak/dev/atom/sim -ferror-limit 19 -fmessage-length 0 -stack-protector 1 -mstackrealign -fblocks -fobjc-runtime=macosx-10.10.0 -fencode-extended-block-signature -fcxx-exceptions -fexceptions -fdiagnostics-show-option -vectorize-slp -o /var/folders/r_/pmd7rtcd4h35dqsf496nyzsh0000gn/T/main-d500bd.o -x c++ /Users/aliak/dev/atom/sim/main.cpp
clang -cc1 version 6.0 based upon LLVM 3.5svn default target x86_64-apple-darwin14.1.0
ignoring nonexistent directory "/usr/include/c++/v1"
#include "..." search starts here:
#include <...> search starts here:
 /Library/Developer/CommandLineTools/usr/bin/../include/c++/v1
 /usr/local/include
 /Library/Developer/CommandLineTools/usr/bin/../lib/clang/6.0/include
 /Library/Developer/CommandLineTools/usr/include
 /usr/include
 /System/Library/Frameworks (framework directory)
 /Library/Frameworks (framework directory)
Run Code Online (Sandbox Code Playgroud)

我只是无法弄清楚出了什么问题.如果我添加-nostdinc++到命令行args to clang然后删除iostream include,但保留时间var,一切都好.我猜这意味着iostream包括time.h. 但我很困惑,如果它不包括ctime而不是time.h,它会将所有内容包装在std命名空间中?

我已经尝试删除xcode并重新安装.

更新:

来自Mats的评论让我做了一点点窥探.因此传入-H到clang ++会打印出标题树.事实证明pthread.h实际上包括time.h. 但是ctime实际上也包括time.h. 这似乎符合标准,因为:"但是,在C++标准库中,声明(除了在C中定义为宏的名称除外)都在命名空间std的命名空间范围(3.3.6)内.它是否未指定这些名称首先在全局命名空间范围内声明,然后通过显式using-declarations注入命名空间std "

Mat*_*son 5

time()是标准C中的一个函数,这意味着它位于命名空间之外,因此可以使用C++编译器编译"旧"C代码,而不会using namespace std在所有地方抛出大量内容.

time.h当你包含时<iostream>,显然包含了标题,这就是你得到它的参考.

要么不使用该名称,要么在要引用变量时添加namespace MyName { int time; };然后使用MyName::time.

[我不知道确切的地方,但我相信C++标准规定" std::当您包含时,现有的标准库函数可能存在或不存在于命名空间之外<ctime>- 实际的实现<ctime>几乎肯定包含在<time.h>某处."

例如在我的linux盒子上的g ++ 4.9.2标题中:

....
#pragma GCC system_header

#include <bits/c++config.h>
#include <time.h>

#ifndef _GLIBCXX_CTIME
#define _GLIBCXX_CTIME 1

 ...     
namespace std
{
  ...
  using ::time;
  ...
} // namespace
Run Code Online (Sandbox Code Playgroud)

libcxx中的那个看起来几乎相同.