standard namespace

C

Comp1597

I have included cmath and I find that I can call the square root
function by either std::sqrt or sqrt
For example, I can calculate std::sqrt(3.0); or sqrt(3.0);

However, std::cout from <iostream> insists on the std qualifier. The
unqualified cout << "I love c++ "; won't compile.

Why is it that sqrt doesn't need a std:: qualifier but cout does?

I'm using visual c++ express.

Thanks for your help.
 
V

Victor Bazarov

I have included cmath and I find that I can call the square root
function by either std::sqrt or sqrt
For example, I can calculate std::sqrt(3.0); or sqrt(3.0);

However, std::cout from <iostream> insists on the std qualifier. The
unqualified cout << "I love c++ "; won't compile.

Why is it that sqrt doesn't need a std:: qualifier but cout does?

Functions and types defined in C headers (like <cmath>) are difficult to
keep only inside 'std' namespace, so they tend to "escape" into the
global namespace as well. With types and objects that are specific to
C++, like 'cout', there is no such problem, they are defined only in the
'std' namespace.

V
 
A

Alf P. Steinbach

* (e-mail address removed):
I have included cmath and I find that I can call the square root
function by either std::sqrt or sqrt
For example, I can calculate std::sqrt(3.0); or sqrt(3.0);

However, std::cout from <iostream> insists on the std qualifier. The
unqualified cout << "I love c++ "; won't compile.

Why is it that sqrt doesn't need a std:: qualifier but cout does?

I'm using visual c++ express.

Very few compilers, if any, are standard-conforming regarding the requirement
that a <c...> header does not introduce names in the global namespace.

The standardization way of dealing with that is to allow the existing dirty
practice, which is what C++0x will do.

The rational in-practice way to deal with it is therefore to not use those
headers, use <...h> headers (although has James Kanze has remarked in an earlier
thread about this, in some corner case you might need to have the std::
qualification available, in which case additionally or instead use <c...>).


Cheers & hth.,

- Alf
 
J

James Kanze

I have included cmath and I find that I can call the square
root function by either std::sqrt or sqrt
For example, I can calculate std::sqrt(3.0); or sqrt(3.0);
However, std::cout from <iostream> insists on the std qualifier. The
unqualified cout << "I love c++ "; won't compile.
Why is it that sqrt doesn't need a std:: qualifier but cout does?

The official reason is that there is a bug in your
implementation. According to the standard, including <cmath>
only introduces symbols in std::.

Practically, however, there are very pertinent arguments for
having the C++ implementation use the C library implementation,
and that makes it extremely difficult, if not impossible, to
make ::sqrt illegal. Most implementations don't bother, and the
next version of the standard won't require it.

This only affects components symbols in the C library
facilities, of course. Things like iostream or vector, which
are pure C++, are only defined in std::.
 
A

Alf P. Steinbach

* Jeff Schwab:
The rational, in-practice way to deal with it is to use the <c*>
headers, but be aware that the global namespace may be polluted.

That may help with being socially conforming, which is important in some
environments, and you're saying, by claiming that it's rational for you, that
being socially conforming is very important in your environment -- OK.

However, using a header whose sole purpose is to not pollute the global
namespace, but "being aware" that in practice it does pollute the global
namespace, i.e. using a header that in practice does not achieve its sole
purpose, is just plain stupid with respect to *good programming*, for it is

* to actively provide disinformation to the reader of the code, and

* to make the compiler unable to report non-standard use or lack of
qualification.

Regarding the latter point, the in-practice is that <cXXX> allows more than the
standard requires of that header, i.e. possibility of writing non-portable code,
while <XXX.h> allows less than the standard requires of that header.

But that point is IMHO not so important, because there is almost no work
involved in fixing code that should turn out to not compile with some compiler.
The first point is however important. For simply by using <cXXX> one helps to
disseminate incorrect beliefs about it, including that it is of some value.

Using a wrapper header without without any positive advantage and with the
disadvantages of disinforming the reader and restricting how much the compiler
can help you, when there is a good alternative, just says: this programmer has
not understood one iota of what the header he or she is using, is about.


Cheers & hth.,

- Alf
 
A

Alf P. Steinbach

* blargg:
Alf said:
* Jeff Schwab:
That may help with being socially conforming, which is important in some
environments, and you're saying, by claiming that it's rational for you, that
being socially conforming is very important in your environment -- OK.

However, using a header whose sole purpose is to not pollute the global
namespace, but "being aware" that in practice it does pollute the global
namespace, i.e. using a header that in practice does not achieve its sole
purpose, is just plain stupid with respect to *good programming*,
[...]

I'd agree if the above were the reasoning, but the <c*> headers DO
reliably put those names IN namespace std, so that one can consistently
refer to standard names with std:: in one's own code.

Puzzling.

What advantage do you see in that?

* It's an advantage for you to write std::printf instead of just printf?

* It's an advantage for you to make the compiler unable to diagnose writing
just printf, or size_t, in code where that name isn't formally available?

* The coding guidelines require qualification of the names from the standard
library that *can* be qualified (conforming to a verbosity requirement)?

Huh.


Cheers & hth.,

- Alf
 
J

James Kanze

The rational, in-practice way to deal with it is to use the
<c*> headers, but be aware that the global namespace may be
polluted.

It's more complicated than that. If you use the <c*> headers,
you may accidentally omit the std::; your code will compile
anyway, but it won't necessarily compile with other compilers.
And of course, if you're using Posix as well, the contents of
the <*.h> headers is well defined---and not conform with the C
or C++ standard; the contents of the <c*> headers isn't. So if
you're using any of the Posix features which Posix (wrongly,
IMHO) put into a standard C header, you more or less have to use
the <*.h> forms.
 
J

James Kanze

* blargg:

[...]
What advantage do you see in that?
* It's an advantage for you to write std::printf instead of
just printf?

You can also write ::printf, if you're paranoid about it. (I
sometimes do---I've had at least one class which had a member
fucntion abort. Which ended up calling ::abort(), after some
logging.)

Note too that while you can (and officially have to) write
std::abort() is you include <cstdlib>, you still have to write
assert(...), without the std::. If you include <stdlib.h>, you
can write both abort() and assert(...), and be sure that both
will be found (except in extreme cases like I just mentionned).
Of course, assert and errno are about the only cases where I
think this argument holds.
* It's an advantage for you to make the compiler unable to
diagnose writing just printf, or size_t, in code where
that name isn't formally available?

One data point: I switched to the <c*> forms a few years ago
(after resisting for a long time). I'm now switching back,
precisely because of this problem: the compilers I usually use
don't detect if I accidentally omit an std::, but one compiler
that I very occasionally use does. The first time I compiled
with this compiler, I found ten or twelve errors due to a
missing std::. Easy to fix, of course, but why bother. In my
case, at least, this is a real reason to not use the <c*>
headers.
 
J

Juha Nieminen

James said:
Most implementations don't bother, and the
next version of the standard won't require it.

I'm a bit worried that the next standard will simply *allow* the
compiler to do it, rather than forcing it.

If the standard simply allows it then you can't rely on it nor write
code assuming it.
 
B

Bo Persson

Juha said:
I'm a bit worried that the next standard will simply *allow* the
compiler to do it, rather than forcing it.

If the standard simply allows it then you can't rely on it nor
write code assuming it.

The standard is just documenting existing practice.

Isn't that what a standard document is supposed to do? :)


Bo Persson
 
A

Alf P. Steinbach

* blargg:
Alf said:
* blargg:
Alf P. Steinbach wrote: [...]
I'd agree if the above were the reasoning, but the <c*> headers DO
reliably put those names IN namespace std, so that one can consistently
refer to standard names with std:: in one's own code.
Puzzling.

What advantage do you see in that?

* It's an advantage for you to write std::printf instead of just printf?

It's an advantage to be ABLE to write std::whatever when whatever is a
name from the standard library, rather than having to write
std::whatever for some names, and whatever for others.

Your "whatever" being no qualification or "::" qualification, which is less to
write, and less to read -- in short, less work and more clear. :)

In most header
files, you don't want a using directive, so the consistency is a
benefit:

// foo.hpp

#include <vector>
#include <cmath>

// using namespace std; // NO, we don't want this in a header

class Foo {
std::vector<double> v;
public:
Foo();
double bar() const { return std::sqrt( v.front() ); }
void f();
// ...
};

Compare that to writing "::sqrt" wherever (seldom occurs) qualification is
necessary.

Perhaps "std::sqrt" could help an utter novice. Aha, dang!, that "sqrt" comes
from the "std" library, probably the standard library, and it's probably -- a
square root function, I think! But should such a novice maintain the C++ code?

And you cannot qualify all names from the standard library.

So there is no full consistency to maintain: even if that, for some obscure
reason, should be desirable, it is not possible.

And having dismissed those 2 silly cases, what on Earth is the advantage you see
in the more verbose code?

I didn't say this, and above I explicitly agreed with your reasoning
that this aspect is bad. Don't act so puzzled.


Only in a header file where you don't want a using directive; in a
source file, you'd rather drop std:: entirely:

// foo.cpp

#include "foo.hpp"
#include <algorithm>
using namespace std;

Foo::Foo()
{
v.push_back( exp( 1 ) );
}

void Foo::f()
{
transform( v.begin(), v.end(), v.begin(), sqrt );
}

Again, this allows consistency.

(I really don't want to start skipping your posts again, but your
discussion style is very abrasive, the way you re-frame things to try
to make others look unreasonable. It had seemed like you changed
somewhat recently...)

Hm, I can't help others posting unreasonable stuff.

At least, I haven't yet figured out a way to stop them from doing so.

As an example, it's extremely rude of you to resort to an ad hominem attack like
above, and very few if any reading that will let it reflect negatively on the
person you attacked that way. :)


Cheers & hth.,

- Alf
 
D

Default User

Jeff said:
James Kanze wrote:

If one uses the .h headers, the code will be non-portable to any
platform that does not provide them.

That would be a broken compiler.
Those headers are deprecated,

Deprecated does not mean optional.
It is my sincere wish that the deprecated, must-be-C-compatible,
namespace-polluting headers eventually die off, but that will never
happen as long as developers continue to use them instead of more
modern substitutes.

In practice the C headers will remain for cross-compatibility with C.
Enough library creators want that sort of thing that the C headers
aren't going anywhere.




Brian
 
A

Alf P. Steinbach

* blargg:
The problem exists the other way too; one compiler might put some of the C
names into std::, and others not, and your code accidentally name it from
std:: and not work on the other compilers.

Do you have a concrete example?

Consider that most vendors use the same code for C and C++ for a [.h] header,
with the C++ header including the C one instead of the opposite (which would be
one way to conform to the standard's requirements).

I find it very doubtful that such a C header would introduce any names in any
C++ namespace other than the global namespace, since that wouldn't work with C.
So while the standard seems to[1] require that [XXX.h] puts names in both std
and global namespace, the in-practice is that it doesn't. So while there is
reverse version of the problem it is in practice purely formal... ;-)


Cheers & hth.,

- Alf

Notes:
[1] The wording of the normative part is apparently garbled, at least to me, so
one/I must guess about intention from the non-normative explanation note!
 
J

James Kanze

Alf said:
* blargg:
Alf P. Steinbach wrote: [...]
I'd agree if the above were the reasoning, but the <c*>
headers DO reliably put those names IN namespace std, so
that one can consistently refer to standard names with
std:: in one's own code.
Puzzling.
What advantage do you see in that?
* It's an advantage for you to write std::printf instead
of just printf?
It's an advantage to be ABLE to write std::whatever when
whatever is a name from the standard library, rather than
having to write std::whatever for some names, and whatever for
others.

I'm not sure I follow. In my projects, I'm using several
standard libraries: C++, Posix, Sybase... And I do have to keep
them straight; I can't write std::pthread_mutex_init, for
example. And the look and feel of the C library is closer to
Posix than it is to C++, so it actually seems more natural to
not use std::. How is time, in time.h, different from poll, in
poll.h? And what about popen, in stdio.h (but not necessarily
in <cstdio>---at least, I can't find a document anywhere that
guarantees it). Not to mention that two of the most used
facilities in the C library, assert and errno, are macros, and
will be without the std:: even if I use the said:
In most header files, you don't want a using directive, so the
consistency is a benefit:

Consistency is an enormous benefit. None of the other C
libraries I use (Posix, etc.) put their names in std::, so why
should the standard C library?

[...]
Only in a header file where you don't want a using directive;
in a source file, you'd rather drop std:: entirely:

I disagree. Within a function, you might use a using
declaration, to shorten the name, but otherwise: the name of the
standard input in C++ is std::cin, not cin, and that's the way
you normally write it.
 
J

James Kanze

If one uses the .h headers, the code will be non-portable to
any platform that does not provide them.

And which platforms are those? They're required by the
standard. They're also required by C, and I can't imagine a
platform supporting C++, but not C.
Those headers are deprecated,

Deprecated doesn't mean anything.
and subtly different from the c* headers.

The only subtle difference I know is that I know exactly what is
in them said:
Futhermore, I don't want something as simple as "using
std::printf" to be an error.

Actually, I'd like for any use of printf to be an error:). (At
compile time---it frequently does end up being an error at run
time.)

But why would you use std::whatever for a function which is
defined in the C standard (or the Posix standard)? And of
You're talking about two different libraries, POSIX and C++
standard, with similar but different headers.

Sort of. Some of the Posix headers have the same names as the C
headers---if I wanted popen said:
If you need POSIX headers, include them. If you need C++
headers, include those, too.

And if I need the C headers, I include those. Sounds logical to
me: if the function I use is defined in the C standard, I
include the header defined in the C standard. Even if the C++
standard includes it by reference.
But it's a bad idea to just omit the formally preferred C++
headers, since what the heck, you've pretty much got what you
want already from POSIX.
It is my sincere wish that the deprecated,
must-be-C-compatible, namespace-polluting headers eventually
die off, but that will never happen as long as developers
continue to use them instead of more modern substitutes.

They won't die off as long as there is C. And theirs no point
in not using them as long as parts of the contents are macros,
and other standards organizations, like Posix, extends them for
its own purposes.

My sincere wish is that we get well designed, C++ components for
all of the functionality in them, so I don't have to drop back
into C for e.g. things like time---whether the function's name
is strftime or std::strftime, it's pure C in its interface, not
C++.
 
J

James Kanze

I'm a bit worried that the next standard will simply *allow*
the compiler to do it, rather than forcing it.
If the standard simply allows it then you can't rely on it nor
write code assuming it.

I agree (if I understand your point correctly): a program should
be either legal, or illegal, and if it is illegal, a compiler
should be required to diagnose the fact. But as it stands,
there are so many violations of this rule that it doesn't
matter. I try to be very careful in my code, but I regularly
have to add includes when porting to another compiler, for
example, because unlike C, the C++ standard allows (but does not
require) an implementation to include other standard headers
from a standard header. (C forbids a standard header from
including any other standard header. This really isn't tenable
in C++---how do you implement <istream> without including <ios>,
or <vector> without including <memory>? But the standard could
specify exactly which headers were included, so we could count
on it.)

From this point of view, of course, the <*.h> headers are to be
preferred. As Alf points out, regardless of what the standard
allows, in practice, none will put any of the symbols in std::,
so you're forced to be coherent.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,160
Messages
2,570,889
Members
47,423
Latest member
henerygril

Latest Threads

Top