Are C keywords/functions not enclosed in std namespace in C++?
The standard says that when you include any standard include file it is possible that this will include other include files. It is implementation dependent which ones and how many of them.
The implication is that your code simply must not define any global name that is also standard.
I can understand this seems a difficult requirement (indeed it is) and also that makes one wonder why there are standard include files at all and we don't have simply the whole standard available instead (that's a good question). But none the less this is the situation.
Situation is even worse with POSIX where not only random names are reserved, but also quite a lot prefixes and suffixes; for example code that use any name starting with LC_
followed by an uppercase letter in any way is possibly clashing with #define
s related to locale support. Any name that ends with _t
is also reserved, not joking. The list is huge.
As a general rule try to define the least possible amount of global names and avoid anything that is also used by the standard library. Even when "it works" on your compiler, your program may find the problem when ported to another compiler (or the next version of the same compiler). Avoiding defining global names makes also easier for your code to be integrated in larger programs with code written by others. Ideally your code should just have one global name (a namespace, a single class or a single function)... unfortunately with C++ you cannot get below that.
Something I remember bumping in when writing small C++ experiments when I usually don't care about these name clashing problems is for example y0
that is a standard Bessel function (this is not a joke; there is a global standard function double y0(double)
and any program that uses y0
for anything else at global level is not a valid C++ program).
You include the header file time.h
indirectly. In this header file there is a declaration of a function named time
that is in conflict with your declaration.
Just change the variable time
to another name (time_1
).
Are C keywords/functions not enclosed in std namespace in C++?
Keywords (and also macros): No, those are not in namespaces.
Functions, types and variables (i.e. all identifiers except macros): Depends on which standard header you include.
If you include C standard header such as <stdint.h>
, then the names will be in the global namespace. They may also be in the std
namespace, but that is not guaranteed.
If you include the corresponding <cstdint>
header, then the names from the C standard header are guaranteed to be in the std
namespace. They may also be in the global namespace, but that is not guaranteed.
You've failed to include either <stdint.h>
or <cstdint>
, so there is no guarantee that int32_t
would be declared in either namespace. But you've included another standard header and therefore there is no guarantee that it wouldn't be declared in some namespace - because standard headers may include other headers; you should never rely on such transitive inclusion (in the way that your example relies on it) unless documented in the standard.
Same applies to the time
function. You've included a standard header and there is no guarantee that it wouldn't include another standard header which declares time
. And there is no guarantee that it wouldn't be in the global namespace.
Regardless of whether you include any standard headers, all names used by the C standard library are reserved to the language implementation in the global namespace. By defining ::time
yourself, the behaviour of your program will be undefined (UB is allowed to fail compilation, which is the best outcome).
Can I be assured that there would be no problem with the name clashing if I declare variables in local space?
In case of time
, Yes. C standard names (except macros of course) are reserved only in the global namespace. Local names are not in the global namespace; they will shadow the global one, which is fine. It is also fine to define these in your own custom namespace.
Macro names, as well as certain identifiers such as those that include double underscore are reserved in all namespaces. All macro names are all upper case, so it is easy to avoid them by including lower case characters in names.
To avoid name conflicts with standard names, as well as third party libraries, one should only declare one name in the global namespace (besides main
): A (hopefully unique) namespace that contains all other namespace scope declarations. And macros should be avoided when possible, but where necessary, they should include some (hopefully unique) prefix.