Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Ascertaining if objects are in the standard namespace

57 views
Skip to first unread message

Paul

unread,
Oct 28, 2015, 5:37:11 PM10/28/15
to
Is there any way of ascertaining (other than looking it up) whether objects are in the standard namespace? For example, INT_MIN from the <climits> header is not in the std namespace but cout from <iostream> is in the std namespace.
How could one deduce that beforehand to avoid compile errors from writing std::INT_MIN?

Is the rule that functions from header files are in the std namespace but variables from header files are not in the std namespace? Or is it subtler? Or something else I haven't thought of?

Thanks,

Paul

Alf P. Steinbach

unread,
Oct 28, 2015, 6:23:01 PM10/28/15
to
On 10/28/2015 10:36 PM, Paul wrote:
> Is there any way of ascertaining (other than looking it up) whether objects are
> in the standard namespace? For example, INT_MIN from the <climits> header is
> not in the std namespace but cout from <iostream> is in the std namespace.
> How could one deduce that beforehand to avoid compile errors from writing
> std::INT_MIN?

As evident from the all uppercase name, INT_MIN is a macro.

A macro is not in any namespace: it is a text substitution rule.


> Is the rule that functions from header files are in the std namespace
> but variables from header files are not in the std namespace? Or is it
> subtler? Or something else I haven't thought of?

Generally,

* Identifiers from the pure C++ part of the standard library are in the
std namespace.

* Identifiers from the C standard library (which is mainly wholesale
adopted into the C++ standard library) can be in the std namespace, or
in the global namespace, or both, depending on which header you include.

Heads-up: the last point is COMPLICATED.

So, here's a concrete example.

In C the "<string.h>" header declares functions such as "strcpy".

In C++ the basic corresponding header is "<cstring>". Unlike C, when you
include "<cstring>" you're only guaranteed that "strcpy" is available in
the std namespace. C++ code that refers just to unqualified strcpy, may
fail to compile, while in C that's how it has to be expressed. But with
"<cstring>" the identifiers may also be placed in the global namespace,
so that unqualified name usage can compiler; it's just not guaranteed to
compile.

Originally for backwards-compatibility and leveraging existing
expertise, C++ also provides a header "<string.h>", which is distinct
from the original C "<string.h>". The effect of including "<string.h>",
like in C programming, is to get every name from "<cstring>" placed in
the global namespace, without necessarily being available in the std
namespace.

This means that when you include "<string.h>" in C++, you MAY get the
identifiers also available in the std namespace, and there's no way to
check that in the C++ code.

Effectively this means that there's no point in using "<cstring>": it
has negative utility because it presents possible portability issues,
with code that uses unqualified "strcpy" (for example) compiling nicely
with the original compiler, and then failing with some other compiler.
So, use "<string.h>".

And be aware that none of the three headers discussed above, namely C's
"<string.h>", C++'s "<cstring>", and C++'s "<string.h>", have ANYTHING
to do with C++' "<string>", which declared std::string and std::wstring
+ support.

Cheers & hth.,

- Alf

Victor Bazarov

unread,
Oct 29, 2015, 8:04:55 AM10/29/15
to
If you know that it's a macro you can only use #ifdef {macroname},
otherwise when the compiler gets to it, the name has already been
substituted with its meaning.

If it's an object (like 'cout'), you could try taking its address and
wrap it in a SFINAE definition/declaration (nothing on the top of my
head, though).

V
--
I do not respond to top-posted replies, please don't ask

Jorgen Grahn

unread,
Oct 29, 2015, 8:40:16 AM10/29/15
to
What problem are you trying to solve? To mistype and have the
compiler correct you, that's not such a great burden[0].

"assert" and anything in CAPITALS are macros, the rest is in std --
I think that's a pretty good rule of thumb.

/Jorgen

[0] Gone are the days of batch programming where you'd get the
compilation error on paper the next morning ...

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Vir Campestris

unread,
Oct 29, 2015, 5:28:54 PM10/29/15
to
I know no rule. But in this case couldn't you use
std::numeric_limits<int>::min() ?

Andy

Richard

unread,
Oct 30, 2015, 12:27:13 AM10/30/15
to
[Please do not mail me a copy of your followup]

"Alf P. Steinbach" <alf.p.stein...@gmail.com> spake the secret code
<n0rhnj$vho$1...@dont-email.me> thusly:

>Effectively this means that there's no point in using "<cstring>": it
>has negative utility because it presents possible portability issues,
>with code that uses unqualified "strcpy" (for example) compiling nicely
>with the original compiler, and then failing with some other compiler.
>So, use "<string.h>".

While I agree with your analysis, I don't agree that <cstring> has
negative utility. I *want* those C-style library calls pushed off
into namespace std and that's why I use <cstring>. A proper
implementation will put those names only in namespace std and not dump
them anywhere else. Additionally, there are some changes to the
signatures of these C library functions mandated by the C++ standard
when they are included as <cstring> that are not present when included
as <string.h>. See 21.7 [c.strings] in the C++11 standard, for
instance.

Furthermore, things that are declared as macros when including the C
style header are mandated to be declared as functions when including
the C++ header. Look at how table 74 describes things like isalnum
and tolower in the standard. It refers to them as functions, not as
macros. This is reasonable in C++ because it has inline functions,
but in C this would traditionally be done with a macro. So when using
<cctype>, I should get fewer preprocessor surprises because something
was declared as a macro instead of being declared as a proper inline
function.

I'm not sure how conforming actual implementations are to this wording,
however. For a long time people took shortcuts that lead to the kinds
of problems you describe. However, I would rather be clear about my
intent -- including the C++ version of a C library header with
<cstring> -- and deal with the occasional compile error because I
forgot the std:: prefix.
--
"The Direct3D Graphics Pipeline" free book <http://tinyurl.com/d3d-pipeline>
The Computer Graphics Museum <http://computergraphicsmuseum.org>
The Terminals Wiki <http://terminals.classiccmp.org>
Legalize Adulthood! (my blog) <http://legalizeadulthood.wordpress.com>

Alf P. Steinbach

unread,
Oct 30, 2015, 12:51:05 AM10/30/15
to
On 10/30/2015 5:26 AM, Richard wrote:
>
> [...] there are some changes to the
> signatures of these C library functions mandated by the C++ standard
> when they are included as <cstring> that are not present when included
> as <string.h>. See 21.7 [c.strings] in the C++11 standard, for
> instance.

You're missing that the C++ "<string.h>" header is defined in terms of
C++ "<cstring>", which in turn is defined in terms of the C "<string.h>".

I.e. those requirements on C++'s "<cstring>" automatically apply also to
the C++ "<string.h>".

In the C++11 standard that's in §D.5/2,

<quote>
Every C header, each of which has a name of the form `name.h`, behaves
as if each name placed in the standard library namespace by the
corresponding /cname/ header is placed within the global namespace
scope. It is unspecified whether these names are first declared or
defined within namespace scope (3.3.6) of the namespace std and are then
injected into the global namespace scope by explicit using-declarations
(7.3.3).
</quote>

Btw. that might sound as if "<string.h>" assuredly also provides the
identifiers in the std namespace, but a following example makes clear
that it doesn't need to.


> Furthermore, things that are declared as macros when including the C
> style header are mandated to be declared as functions when including
> the C++ header. Look at how table 74 describes things like isalnum
> and tolower in the standard. It refers to them as functions, not as
> macros. This is reasonable in C++ because it has inline functions,
> but in C this would traditionally be done with a macro. So when using
> <cctype>, I should get fewer preprocessor surprises because something
> was declared as a macro instead of being declared as a proper inline
> function.

Nope, the requirements are the same, except for namespaces.


> I'm not sure how conforming actual implementations are to this wording,
> however. For a long time people took shortcuts that lead to the kinds
> of problems you describe. However, I would rather be clear about my
> intent -- including the C++ version of a C library header with
> <cstring> -- and deal with the occasional compile error because I
> forgot the std:: prefix.


Jorgen Grahn

unread,
Oct 30, 2015, 4:35:20 AM10/30/15
to
On Fri, 2015-10-30, Richard wrote:
> [Please do not mail me a copy of your followup]
>
> "Alf P. Steinbach" <alf.p.stein...@gmail.com> spake the secret code
> <n0rhnj$vho$1...@dont-email.me> thusly:
>
>>Effectively this means that there's no point in using "<cstring>": it
>>has negative utility because it presents possible portability issues,
>>with code that uses unqualified "strcpy" (for example) compiling nicely
>>with the original compiler, and then failing with some other compiler.
>>So, use "<string.h>".
>
> While I agree with your analysis, I don't agree that <cstring> has
> negative utility. I *want* those C-style library calls pushed off
> into namespace std and that's why I use <cstring>.

Agree. I don't want a distinction between "function I use which
originated in C" and "function that's new for C++".

It gets trickier when you're e.g. writing Unix code, and something
POSIX-specific is defined to live in one of the C header files. Then
I use <foo.h> rather than <cfoo>.

...
> of problems you describe. However, I would rather be clear about my
> intent -- including the C++ version of a C library header with
> <cstring> -- and deal with the occasional compile error because I
> forgot the std:: prefix.

Especially since there are other such sources of errors, like
accidentally relying on foo.h to pull in bar.h, even if the standard
doesn't guarantee that it does.

/Jorgen

Juha Nieminen

unread,
Oct 30, 2015, 5:50:48 AM10/30/15
to
Alf P. Steinbach <alf.p.stein...@gmail.com> wrote:
> As evident from the all uppercase name, INT_MIN is a macro.

The standard does not always follow that naming convention. Counter-examples:

assert()
std::FILE

(We may blame C for this, but it is there in the C++ standard nevertheless.)

--- news://freenews.netfront.net/ - complaints: ne...@netfront.net ---
0 new messages