Reputation: 13040
I can only find in the standard draft N4582 that
[res.on.headers/1] A C++ header may include other C++ headers.
It seems not to specify that whether a C++ header can include a C standard header.
If it is permitted, is it unsafe to use a global name defined in a C standard header even if this header is not included (since the program may implicitly include the header through some C++ standard header)?
Upvotes: 15
Views: 595
Reputation: 14454
My answer comes late but adds something the others do not, so here goes....
Short answer: whether the standard allows a standard C++ header to include a standard C header remains unclear.
Other answers have correctly observed that the C++ standard
What remains unclear is whether a standard C header is a standard C++ header. I can give evidence both ways.
Why a C header is indeed a C++ header
On GCC 6.24 with GNU's standard C library 2.24, the following test fails to compile.
#include <iostream>
namespace {
const int printf {42};
}
int main()
{
std::cout << printf << "\n";
return 0;
}
The compiler complains, "reference to ‘printf’ is ambiguous," despite that the test lacks an explicit #include <cstdio>
.
The judgment of the developers of a major compiler and standard library like GCC and GNU is hardly to be ignored.
Other answers have given further reasons I need not reprise here.
Why a C header is not a C++ header
The C++17 standard (draft here), footnote 166, reads:
[T]he C++ headers for C library facilities may ... define names within the global namespace.
If C headers were C++ headers, then that would be an odd way to have written such a footnote, would it not? One would instead have expected the footnote to begin with words like, "The non-<*.h>
C++ headers for C library facilities ..."
The last observation is inconclusive but, in [res.on.headers], the standard also reads:
The C standard library headers shall include only their corresponding C++ standard library header....
Again, if C headers were C++ headers in the estimation of the person that wrote the words, then that would seem an odd way to have written them.
Conclusion: ambiguous
Unfortunately, like other answerers, I cannot find a clear answer in the standard one way or the other. Unlike other answerers, I would conclude that the answer remains ambiguous. Relevant sections in the standard include [contents], [res.on.headers] and [depr.c.headers].
Opinion
If you wish to know which alternative carries the preponderance of the evidence in my opinion, then I would tend to disagree with the other answers. For the reasons cited, I would tend to say that the standard did not allow a standard C++ header to include a standard C header. Such inclusion contradicts ordinary C++ usage, at any rate, insofar as such inclusion makes anonymous global namespaces harder to use. [Change printf
to foo
in my test and then ask what would happen if a future standard C library added a function foo()
. Such an experiment illustrates the trouble.]
On the other hand, fighting one's toolchain is fairly pointless, isn't it? Until a future version of C++ clarifies, I for one mean to avoid anonymous global namespaces in source files that include standard library headers.
I suspect that, since the standard has deprecated the old styles by which standard C headers are used, the standards committee might not be thinking too hard about how to patch problems with the old style in the meantime. Maybe C++20 modules will afford a neat solution. We shall see.
Upvotes: 0
Reputation: 171127
For the purpose of the question you follow up with (name conflicts), yes, it certainly can. The reason is that the C++ standard library includes the <c:::>
C++ headers for the C standard library contents, and the standard explicitly allows these to provide the names in the global namespace as well (in addition to mandatorily providing them in ::std
).
Further, based on Annex D [depr] of the C++ standard, the C standard library headers (the <:::.h>
versions) are also part of the C++ standard library (albeit deprecated). This means [res.on.headers]/1 allows C++ headers to include them.
Upvotes: 5
Reputation: 15969
Section D.3 C standard library headers of the C++ standard makes 26 C standard headers part of C++. Thus those are part of C++. Also many other C headers adhere to the shared subset of the languages (probably by #ifdef
ing some things out) making them both, valid C and C++ headers.
Upvotes: 4