namespace std and standard headers

S

Simon Elliott

If I include both of these headers in a c++ source file:

#include <stdio.h>
#include <cstdio>

would I then be able to do both of:

std::printf("Hello, world!\n");
printf("Hello, world!\n");
 
R

remus.dragos

Simon said:
If I include both of these headers in a c++ source file:

#include <stdio.h>
#include <cstdio>

would I then be able to do both of:

std::printf("Hello, world!\n");
printf("Hello, world!\n");

It seems that you can do both but this is not a recommended as a good
programming practice because you can get into obscure errors or worse
you can mix them and compile but execute erroneous.
If you know what you are doing you may save yourself from some hard
work in C(sometimes)!
 
S

Simon Elliott

It seems that you can do both but this is not a recommended as a good
programming practice because you can get into obscure errors or worse
you can mix them and compile but execute erroneous.
If you know what you are doing you may save yourself from some hard
work in C(sometimes)!

I'm trying to get some legacy code to compile. I wouldn't write new
code like this!
 
J

Jay Nabonne

If I include both of these headers in a c++ source file:

#include <stdio.h>
#include <cstdio>

would I then be able to do both of:

std::printf("Hello, world!\n");
printf("Hello, world!\n");

Keep in mind that these will be separate streams, flushed at different
times. So your output may not come out sequentially as you would expect
without explicit stream flushing.

- Jay
 
H

Howard Hinnant

"Simon Elliott said:
If I include both of these headers in a c++ source file:

#include <stdio.h>
#include <cstdio>

would I then be able to do both of:

std::printf("Hello, world!\n");
printf("Hello, world!\n");

Yes, this should work. Those two print statements should also work if
you only #include <stdio.h>, but your odds are better of it working with
both includes.

-Howard
 
G

Greg Comeau

Keep in mind that these will be separate streams, flushed at different
times. So your output may not come out sequentially as you would expect
without explicit stream flushing.

Mmmm, I seem to recall there is some issues about whether
the C lib incorp'd herein is extern "C" or "C++"'d but not
whether there are things such as buffering issues. IMO the
above is fine AFAIK.
 
B

Branimir Maksimovic

Jay said:
Keep in mind that these will be separate streams, flushed at different
times. So your output may not come out sequentially as you would expect
without explicit stream flushing.

I would not be surprised if cstdio looks like this:
namespace std{
#include <stdio.h>
}
or:
#include <stdio.h>
namespace std{
using printf;
// ......
}
Streams should be synchronized with stdio by default.
std::iostream::sync_with_stdio(false); // unsynchronize

Greetings, Bane.
 
P

P.J. Plauger

I would not be surprised if cstdio looks like this:
namespace std{
#include <stdio.h>
}

I would. It's dead wrong.
or:
#include <stdio.h>
namespace std{
using printf;
// ......
}

That also doesn't conform exactly to the C++ Standard, but
it's a widely adopted practice. It'll probably be made
valid in the next release of the C++ Standard.
Streams should be synchronized with stdio by default.
std::iostream::sync_with_stdio(false); // unsynchronize

Right, though the "unsynchronize" operation may do
nothing (because there's nothing to be gained).

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
D

deane_gavin

P.J. Plauger said:
That also doesn't conform exactly to the C++ Standard, but
it's a widely adopted practice. It'll probably be made
valid in the next release of the C++ Standard.

Have I misunderstood something here - is the following a correct
program?

#include <cstdio>

int main()
{
printf("Hello world\n"); // or should that be std::printf?
}

I always thought that <cstdio> should put its names in the std
namespace only - not in the global namespace as well. 17.4.1.2/4 would
seem to confirm that. But Comeau online, for example, compiles my
program.

Because the

#include <stdio.h>
namespace std{
using printf;
// ......
}

approach is so widespread I have never been keen to use the <cname>
headers instead of <name.h>. If the compiler is likely to let me get
away with including <cstdio> but leaving the std:: off the front of
printf I might as well use <stdio.h> and have a correct program. But if
<cstdio> is allowed to put its names in the global namespace as well as
the std namespace, I'm worrying over nothing.

Gavin Deane
 
P

P.J. Plauger

Have I misunderstood something here - is the following a correct
program?

#include <cstdio>

int main()
{
printf("Hello world\n"); // or should that be std::printf?
}

Should be std::printf, but it sometimes works anyway.
I always thought that <cstdio> should put its names in the std
namespace only - not in the global namespace as well. 17.4.1.2/4 would
seem to confirm that. But Comeau online, for example, compiles my
program.

You're correct about what the C++ Standard *says*. What most
implementations *do* is another matter. And that's because
the C++ committee repeatedly refused to listen to compiler
vendors while drafting the C++ Standard. (Don't forget export
either.)
Because the

#include <stdio.h>
namespace std{
using printf;
// ......
}

approach is so widespread I have never been keen to use the <cname>
headers instead of <name.h>. If the compiler is likely to let me get
away with including <cstdio> but leaving the std:: off the front of
printf I might as well use <stdio.h> and have a correct program. But if
<cstdio> is allowed to put its names in the global namespace as well as
the std namespace, I'm worrying over nothing.

You need to distinguish between what might happen and what you can
rely on. The safe rules are:

-- If you want assuredly to be able to write std::printf, include
<cstdio>.

-- If you want assuredly to be able to write ::printf, include
<stdio.h>.

The C++ Standard says that <cstdio> will not declare ::printf
and that <stdio.h> will also declare std::printf, but neither
of these rules is consistently followed in real life.

HTH,

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
D

deane_gavin

P.J. Plauger said:
You need to distinguish between what might happen and what you can
rely on. The safe rules are:

-- If you want assuredly to be able to write std::printf, include
<cstdio>.

-- If you want assuredly to be able to write ::printf, include
<stdio.h>.

The C++ Standard says that <cstdio> will not declare ::printf
and that <stdio.h> will also declare std::printf, but neither
of these rules is consistently followed in real life.

Very helpful, thank you.

What I actually want is to assuredly avoid incorrect code compiling
successfully. It sounds like I will often get away with

#include <cstdio>

int main()
{
std::printf("stuff\n"); // Remembered the std::
std::printf("more stuff\n"); // Remembered again. Well done me.

// Get distracted for a bit ...

printf("Oops! Forgot std::\n"); // But it probably compiles OK
}

If the rule is likely not to be enforced by the compiler, and I am
likely to forget at some point, I might as well just use <stdio.h> and
avoid the whole problem.

Gavin Deane
 
P

P.J. Plauger

What I actually want is to assuredly avoid incorrect code compiling
successfully. It sounds like I will often get away with

#include <cstdio>

int main()
{
std::printf("stuff\n"); // Remembered the std::
std::printf("more stuff\n"); // Remembered again. Well done me.

// Get distracted for a bit ...

printf("Oops! Forgot std::\n"); // But it probably compiles OK
}

If the rule is likely not to be enforced by the compiler, and I am
likely to forget at some point, I might as well just use <stdio.h> and
avoid the whole problem.

Yep. The use of namespaces to "contain" the Standard C library
was essentially a (predicted) failure.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
S

Simon Elliott

You need to distinguish between what might happen and what you can
rely on. The safe rules are:

-- If you want assuredly to be able to write std::printf, include
<cstdio>.

-- If you want assuredly to be able to write ::printf, include
<stdio.h>.

And if I need to do both? (This is for legacy code; I can't think of
any reason for using both in new code.)
The C++ Standard says that <cstdio> will not declare ::printf
and that <stdio.h> will also declare std::printf, but neither
of these rules is consistently followed in real life.

Yes. I still use Borland C++ Builder a lot, and even the different
versions don't seem to be all that consistent in this respect. You can
even compile the same source file twice and get different results.
 
P

P.J. Plauger

And if I need to do both? (This is for legacy code; I can't think of
any reason for using both in new code.)

Include both headers.
Yes. I still use Borland C++ Builder a lot, and even the different
versions don't seem to be all that consistent in this respect. You can
even compile the same source file twice and get different results.

That's probably because Borland started out with the RogueWave
library, which tries to do what the C++ Standard requires
with C header namespaces, IIRC. Then they tried STLport instead,
which doesn't. Now they're switching to our library, which can
go either way.

P.J. Plauger
Dinkumware, Ltd.
http://www.dinkumware.com
 
S

Simon Elliott

Include both headers.

That's what I hoped you'd say. Thanks for the info.
That's probably because Borland started out with the RogueWave
library, which tries to do what the C++ Standard requires
with C header namespaces, IIRC. Then they tried STLport instead,
which doesn't. Now they're switching to our library, which can
go either way.

Which versions use your library?
 

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
473,755
Messages
2,569,536
Members
45,019
Latest member
RoxannaSta

Latest Threads

Top