Rethinking C ++ variable, global namespace is dirty and I don't know why

so I think I did something really stupid, and I just can't figure it out. The following program causes me a lot of pain:

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

My compilation line: clang++ -std=c++1y --verbose -stdlib=libc++ main.cpp -o main . Override error /usr/include/time.h:116:8: note: previous definition is here , and --verbose shows me this as the order in which the path was included:

 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) 

I just can't understand what happened. If I add args clang to -nostdinc++ on the command line and then remove the iostream include, but save the var time, everything will be fine. I think iostream includes time.h. But I'm rather confused, shouldn't it include ctime instead of time.h, which would wrap everything in the std namespace?

I also tried uninstalling xcode and reinstalling.

Update:

A comment from Mats made me feel a little. Thus, passing to -H in clang ++ displays a header tree. And it turns out that pthread.h is the one that actually includes time. But ctime also actually includes time.h. And this is similar to the standard because: “However, in the C ++ standard library, declarations (except for names that are defined as macros in C) are in the namespace (3.3.6) of the std namespace. It does not indicate whether these are declared names are first in the global namespace area and then inserted into the std namespace using explicit use-declarations "

+6
source share
1 answer

time() is a function in the C standard, which means that it lives outside the namespace, so the "old" C code can be compiled with C ++ compilers without a lot of using namespace std thrown everywhere.

The time.h header seems to be included when you include <iostream> , so you get a link to it.

Either do not use this name, or add namespace MyName { int time; }; namespace MyName { int time; }; and then use MyName::time if you want to access your variable.

[I don’t know the exact place, but I believe in the standard C ++ standards that "existing standard library functions may or may not exist outside the std:: namespace when you include, for example, <ctime> - the actual implementation of <ctime> almost certainly includes a regular <time.h> somewhere.]

For example, in the g ++ 4.9.2 headers in my linux box:

 .... #pragma GCC system_header #include <bits/c++config.h> #include <time.h> #ifndef _GLIBCXX_CTIME #define _GLIBCXX_CTIME 1 ... namespace std { ... using ::time; ... } // namespace 

That in libcxx looks almost identical.

+5
source

Source: https://habr.com/ru/post/982353/


All Articles