2

The recommended way to include the C standard library header <foo.h> in C++ is to include the corresponding C++ header <cfoo>.

Based on my experience this puts some of of the corresponding C constructs into the std namespace, but others at global scope, and sometimes they appear in both places (i.e., in the std namespace and at global scope).

It depends on both the compiler (some like to include size_t only in std and not at global scope, others always have it at global scope), and on the construct (for example neither assert nor error ever seem to appear in the std namespace despite including cassert and cerrno).

What is required of the standard, and is there any simple rule to portably accessing C constructs in relation to the location in or out of the std namespace (something better than using namespace std)?

This question covers the same ground, but the answers there already reflect my understanding that cfoo puts everything in std - but doesn't answer the question of why things like assert and errno don't appear in std in that case, and how to know the full list of similar "exceptions".

BeeOnRope
  • 60,350
  • 16
  • 207
  • 386
  • @GManNickG - that question is a bit narrower (it's asking if stuff appears in the global namespace too - but my question is "how can I portably use any C construct"). The answer to that question seems to be "no" - but that leaves open the question of how to use any given construct. For example, "no" doens't mean that everything does appear in `std` since `assert` certainly doesn't (and probably anything else implemented as a macro). Also, the answers there kind of suck? The accepted one doesn't seem to answer the question (perhaps the quote was truncated). – BeeOnRope Jul 14 '18 at 03:32
  • 1
    in case of doubt, always add `std::` – L. Kue Jul 14 '18 at 03:33
  • @L.Kue - it doesn't work, consider `assert`. – BeeOnRope Jul 14 '18 at 03:33
  • 2
    @BeeOnRope `assert` is a macro, and not a function, hence no `std::` is used. – L. Kue Jul 14 '18 at 03:35
  • @BeeOnRope, The gist of the other Q&A is that including `` will guarantee names in `std::`. As for macros, you'll have to know what's a macro and what isn't. Many of them are all uppercase. – chris Jul 14 '18 at 03:39
  • @L.Kue - sure, I know _why_ `assert` doens't appear in the standard namespace, but how am I supposed to apply that rule in general? `assert` may be documented to always be a macro, and macros may be documented to never appear in `std` (is that true?) - but I in general anything could be implemented as a macro in any particular implementation and I have no idea what those are. Consider for example `errno` which is not documented to be a macro, yet doesn't appear in `std` either on any compiler I tried. – BeeOnRope Jul 14 '18 at 03:43
  • @chris - is it guaranteed by the standard which things are macros and which aren't? The question is how to "know" and whether it is portable. I checked my local implementation and there are things which are implemented as macros, yet appear in the standard namespace (i.e., the macro resolves to something that appears in `std`). The examples I gave of `assert` and `errno` aren't uppercase. – BeeOnRope Jul 14 '18 at 03:46
  • Macros cannot have a namespace as they are not functions that are executed at runtime, they are used by the preprocessor during compile time. As chris said, you'll just have to know what's a macro and what isn't. That said, most IDE's provide you with suggestions for the correct syntax, as well as different syntax highlighting depending on whether something is a macro or a function. – L. Kue Jul 14 '18 at 03:46
  • @BeeOnRope, Macros can't have scope, so none can be in `std`. As for `errno`, see [this](http://eel.is/c++draft/errno#1), which says it's a macro. The standard distinguishes macros. Note that while not all macros are uppercase, very few aren't, so there are few special cases to learn. – chris Jul 14 '18 at 03:47
  • @BeeOnRope I'm not certain if it's defined by the standard, but due to their nature, a macro will be a macro on any platform, and a function will be a function on any platform. – L. Kue Jul 14 '18 at 03:48
  • @L.Kue - it's totally up to the implementation which things are macros, so that is unsatisfactory. – BeeOnRope Jul 14 '18 at 03:48
  • @chris, sure macros can't have scope, but some macro `x` can certainly be "accessible" through `std`, since the macro substitution happens and then the `std::` qualifier is applied after and the result of the macro substitution may result in something appropriate to be prefixed with `std::`. Consider `#define vec vector` and then `std::vec` will "work". – BeeOnRope Jul 14 '18 at 03:52
  • @BeeOnRope, Sure, and I imagine an implementation could fit that under the as-if rule, but it doesn't affect your question in that case because you can't tell the difference; `std::` would be portable. To my knowledge, `(std::)(...)` is supposed to work, so function macros wouldn't be permissible. – chris Jul 14 '18 at 03:59
  • It’s *not* up to the implementation what is macro and what isn’t when using the `` header. Just always use `std::` and if it doesn’t work check the [docs](https://en.cppreference.com/w/cpp/error/errno) to see if it’s supposed to be that way and otherwise file a bug for your implementation. – Darklighter Jul 14 '18 at 04:01
  • Thanks @chris and L. Kue. I think it could be summarized as an answer: "In general everything will appear in the `std::` except things that are necessarily macros (and documented as such) which must be called unqualified. [insert part about determining what is a macro here]". – BeeOnRope Jul 14 '18 at 04:01
  • @BeeOnRope - some things specified in C standard headers are explicitly specified as being macros, and remains as macros in C++ forms of those headers. `assert()` and `errno` are examples of that - they are still macros in the header ``. – Peter Jul 14 '18 at 06:08

1 Answers1

1

Assert and errno are preprocessor macros and them being macros means they don't recognize namespaces and scopes. (preprocessor runs before compilation and does not respect any scope/namespace)

Everything else than macros in those <cfoo> headers should be placed in the std namespace.

pablo285
  • 2,460
  • 4
  • 14
  • 38
  • 1
    So those two macros are the only exceptions - things that don't appear in `::std`? – BeeOnRope Jul 16 '18 at 21:03
  • No, everything that is a macro doesn't appear in `::std` - macros in general have no notion of namespaces. You can't actually put a macro inside a namespace. I will edit my answer accordingly. Thanks for pointing that out. – pablo285 Jul 16 '18 at 21:05
  • I understand that macros have no concept of namespaces and are implemented by the pre-processor. That's not the question. The question is which C constructs don't appear in the `std` namespace? If the answer is 'all of those implemented as macros' then the question is whether that is defined by the standard and where I can look to see what is a macro. – BeeOnRope Jul 16 '18 at 21:09
  • Cppreference is a good resource, you can have a look at to get the idea. https://en.cppreference.com/w/cpp/header/cmath – pablo285 Jul 18 '18 at 19:03