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

Names in <cstring> are in std, right?

6 views
Skip to first unread message

Scott Meyers

unread,
Jun 10, 2004, 7:32:45 PM6/10/04
to
My understanding is that all the C library functions are declared in std if
I use the <c...> headers. Hence I'd expect this to not compile:

#include <cstring>

int main()
{
strlen("Hello");
}

17.4.1.2/4 backs me up, as far as I can tell, so I was astonished to find that
all the compilers I have here (VC6, VC7.1, g++ 3.2, and Comeau 4.3.3) accept
the code, most by having std::strlen call ::strlen.

Am I missing something, or are all these implementations nonconforming?

Thanks,

Scott

---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std...@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html ]

Bert Klaps

unread,
Jun 11, 2004, 12:06:56 PM6/11/04
to
Use...@aristeia.com (Scott Meyers) wrote in message news:<MPG.1b328070...@news.hevanet.com>...

> My understanding is that all the C library functions are declared in std if
> I use the <c...> headers. Hence I'd expect this to not compile:
>
> #include <cstring>
>
> int main()
> {
> strlen("Hello");
> }
>
> 17.4.1.2/4 backs me up, as far as I can tell, so I was astonished to find that
> all the compilers I have here (VC6, VC7.1, g++ 3.2, and Comeau 4.3.3) accept
> the code, most by having std::strlen call ::strlen.
>
> Am I missing something, or are all these implementations nonconforming?

Maybe there is a subtle interaction with extern "C" linkage.
17.4.2.2/2 seems to allow this.

The implementations I've looked at seem to go for extern "C"
linkage for Standard C library functions. This kind of defeats
the std namespace concept since those functions are now available
in the global and the std namespace...

Regards,
Bert Klaps

P.J. Plauger

unread,
Jun 11, 2004, 12:09:33 PM6/11/04
to
"Scott Meyers" <Use...@aristeia.com> wrote in message
news:MPG.1b328070...@news.hevanet.com...

> My understanding is that all the C library functions are declared in std
if
> I use the <c...> headers. Hence I'd expect this to not compile:
>
> #include <cstring>
>
> int main()
> {
> strlen("Hello");
> }
>
> 17.4.1.2/4 backs me up, as far as I can tell, so I was astonished to find
that
> all the compilers I have here (VC6, VC7.1, g++ 3.2, and Comeau 4.3.3)
accept
> the code, most by having std::strlen call ::strlen.
>
> Am I missing something, or are all these implementations nonconforming?

All you're missing is the long history of the discussion of this issue.
It's probably more accurate to say that the *C++ Standard* is nonconforming
in this area. By that I mean that several major compiler vendors warned
the C++ committee on several occasions that they were *not* going to get
the changes to the C headers they were trying to mandate, for a host of
technical and administrative reasons. But the committee stood by their
mantra, "If we standardize it, they will come."

Most still haven't come.

Aside from the notorious export template issue, the use of namespaces
in C headers is the commonest way in which a typical implementation
fails to conform to the precise requirements of the C++ Standard.
What you'll generally find instead is that the C headers put the
names in the namespaces they're supposed to, but they don't necessarily
keep them out of the namespaces they're supposed to. Thus, negative
tests like yours will fail. And implementations often don't define the
C names in the expected namespace, so you can contrive an occasional
Koenig-lookup trick that also fails.

FWIW, you *can* configure our library to fully conform in this
regard. Most of our OEM compiler vendor customers don't bother,
however. And no other C++ library suppliers have sufficient control
over their underlying C libraries to even offer this option. (And
C library suppliers such as the glibc folks have publicly and
repeatedly expressed their indifference to *ever* conforming to
the added requirements of the C++ Standard.)

Also FWIW, I've introduced a request to change the C++ Standard to
match reality, since it's now been a decade since this interesting
experiment was introduced and it's still a failure. I don't yet
have a feeling for its chance of acceptance.

HTH,

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

tom_usenet

unread,
Jun 11, 2004, 12:09:57 PM6/11/04
to
On Thu, 10 Jun 2004 23:32:45 +0000 (UTC), Use...@aristeia.com (Scott
Meyers) wrote:

>My understanding is that all the C library functions are declared in std if
>I use the <c...> headers. Hence I'd expect this to not compile:
>
> #include <cstring>
>
> int main()
> {
> strlen("Hello");
> }
>
>17.4.1.2/4 backs me up, as far as I can tell, so I was astonished to find that
>all the compilers I have here (VC6, VC7.1, g++ 3.2, and Comeau 4.3.3) accept
>the code, most by having std::strlen call ::strlen.
>
>Am I missing something, or are all these implementations nonconforming?

That's correct. The only conforming library I've ever used is
Dinkumware's C/C++ combined library on QNX. *All* others I've used
declare strlen, etc. in the global namespace, and then just add using
declarations in the "c" headers. e.g.

namespace std
{
using ::strlen;
//etc.
}

There is a strong case for saying that the C names *should* be
declared in the global namespace and that the above be the correct
implementation for <cheaders>, and that the committee made a mistake
going down the path they did. However, it is reasonably easy to get
right I think, I think you just need:

//stdio.h
#ifdef __cplusplus
#include <cstdio>
using std::fwrite;
using std::fopen;
//etc.
#else //C version

//normal stdio.h header.

#endif

//cstdio
namespace std
{
extern "C"
{
//declarations
//make sure functions vs macros are correct (as required in C++).
}
//any special overloads required for C++
//(I think you can't overload extern "C" names)
}

The only annoyance for implementor is the potential repeated work
between <cheader> and <header.h>, but they could minimize that by
making use of an extra <impl/header.h> file or similar, included in
both the <cheader> and <header.h> files. But, thanks to the use of
extern "C" in the C++ header, you can just link with the normal C
runtime library, and provide the extra C++ overloads in the C++
runtime library file.

Tom
--
C++ FAQ: http://www.parashift.com/c++-faq-lite/
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html

Greg Comeau

unread,
Jun 11, 2004, 12:10:46 PM6/11/04
to
In article <MPG.1b328070...@news.hevanet.com>,

Scott Meyers <Use...@aristeia.com> wrote:
>My understanding is that all the C library functions are declared in std if
>I use the <c...> headers. Hence I'd expect this to not compile:
>
> #include <cstring>
>
> int main()
> {
> strlen("Hello");
> }
>
>17.4.1.2/4 backs me up, as far as I can tell, so I was astonished to find that
>all the compilers I have here (VC6, VC7.1, g++ 3.2, and Comeau 4.3.3) accept
>the code, most by having std::strlen call ::strlen.
>
>Am I missing something, or are all these implementations nonconforming?

It's always been my understand that this is guaranteed:

#include <stdio.h>

int main()
{
printf("AA\n");
std::printf("BB\n");

return 0;
}

whereas only DD is in this case:

#include <cstdio>

int main()
{
printf("CC\n");
std::printf("DD\n");

return 0;
}

CC is allowed but not guaranteed.
--
Greg Comeau / Comeau C++ 4.3.3, for C++03 core language support
Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?

Gabriel Dos Reis

unread,
Jun 11, 2004, 12:11:39 PM6/11/04
to
Use...@aristeia.com (Scott Meyers) writes:

| My understanding is that all the C library functions are declared in std if
| I use the <c...> headers. Hence I'd expect this to not compile:
|
| #include <cstring>
|
| int main()
| {
| strlen("Hello");
| }
|
| 17.4.1.2/4 backs me up, as far as I can tell, so I was astonished to find that
| all the compilers I have here (VC6, VC7.1, g++ 3.2, and Comeau 4.3.3) accept
| the code, most by having std::strlen call ::strlen.
|
| Am I missing something, or are all these implementations nonconforming?

They are not conforming but your program wasn't conforming either.
The standard does not require much about non-conforming programs
except that a diagnostic should be emitted. It could be argued
weither the fact that GCC took a while to compile is a diagnostic or
not ;-)

--
Gabriel Dos Reis
g...@cs.tamu.edu
Texas A&M University -- Computer Science Department
301, Bright Building -- College Station, TX 77843-3112

Scott Meyers

unread,
Jun 11, 2004, 1:32:17 PM6/11/04
to
On Fri, 11 Jun 2004 16:11:39 +0000 (UTC), Gabriel Dos Reis wrote:
> They are not conforming but your program wasn't conforming either.

True, but it began life as a conforming program that wanted to slap a facade
on some functions in the C library:

#include <cstring>

namespace CWrapper {
std::size_t strlen(const char* p)
{
// do something
std::size_t retVal = std::strlen(p);
// do something
return retVal;
}
}

int main()
{
using namespace CWrapper;

strlen("Test"); // should call CWrapper::strlen, but
} // is ambiguous with impls I tested

Apparently this can't be expected to work. Sigh.

Scott

Ray Lischner

unread,
Jun 11, 2004, 3:14:09 PM6/11/04
to
On Thursday 10 June 2004 07:32 pm, Scott Meyers wrote:

> My understanding is that all the C library functions are declared in
> std if I use the <c...> headers.

The way I read 17.4.3.1.3, all the external names from the C library are
reserved in the global namespace (in addition to reservation in std).
What the implementation does with the global names is not specified,
but it is not surprising that most implementations choose to make ::X
the same as std::X. Thus, ::strlen is permitted, but not required.

Note that 17.4.3.1.4 specifies that all C types are reserved in the
global namespace, but imposes the additional restriction that if ::T is
defined, it must be the same as std::T.
--
Ray Lischner, author of C++ in a Nutshell
http://www.tempest-sw.com/cpp

Martin Sebor

unread,
Jun 11, 2004, 3:14:24 PM6/11/04
to
They're all non-conforming. It's a royal pain in the neck to get these
headers to play with the traditional C headers in a useful way, and
there are only a handful of implementations that managed to do it.
Compaq C++ and SunPro are two of them.

Martin

Eric Backus

unread,
Jun 11, 2004, 4:08:18 PM6/11/04
to
"Scott Meyers" <Use...@aristeia.com> wrote in message
news:MPG.1b328070...@news.hevanet.com...
> My understanding is that all the C library functions are declared in std
if
> I use the <c...> headers. Hence I'd expect this to not compile:
>
> #include <cstring>
>
> int main()
> {
> strlen("Hello");
> }
>
> 17.4.1.2/4 backs me up, as far as I can tell, so I was astonished to find
that
> all the compilers I have here (VC6, VC7.1, g++ 3.2, and Comeau 4.3.3)
accept
> the code, most by having std::strlen call ::strlen.
>
> Am I missing something, or are all these implementations nonconforming?
>
> Thanks,
>
> Scott

Assuming those implementations are somehow conforming, what about the case
of math functions? Take sqrt for example, the C library defines only a
::sqrt(double). But <cmath> defines std::sqrt(double), std::sqrt(float),
and std::sqrt(long double).

Should <cmath> and <math.h> define ::sqrt(float) and ::sqrt(long double)?
I'd argue that they shouldn't, but they do on some implementations. What
does the standard say about this?

--
Eric Backus
R&D Design Engineer
Agilent Technologies, Inc.
425-356-6010 Tel

P.J. Plauger

unread,
Jun 11, 2004, 11:17:17 PM6/11/04
to
""Eric Backus"" <eric_...@alum.mit.edu> wrote in message
news:10869829...@cswreg.cos.agilent.com...

> Assuming those implementations are somehow conforming, what about the case
> of math functions? Take sqrt for example, the C library defines only a
> ::sqrt(double). But <cmath> defines std::sqrt(double), std::sqrt(float),
> and std::sqrt(long double).
>
> Should <cmath> and <math.h> define ::sqrt(float) and ::sqrt(long double)?
> I'd argue that they shouldn't, but they do on some implementations. What
> does the standard say about this?

According to the C++ Standard, if you include <cmath>, you get
std::sqrt(float), std::sqrt(double, and std::sqrt(long double).
If you include <math.h> you get these plus the same names
hoisted to the global name space -- so they appear as ::sqrt(float),
::sqrt(double), and ::sqrt(long double). Oh, and you're also
supposed to get much the same treatment for sqrtf(float) and
sqrtl(long double), even though neither is required by C89.

The mix of opinions expressed in this thread so far tells you why
there has been less hue and cry over namespaces and C headers than
over export templates.

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

---

Gabriel Dos Reis

unread,
Jun 12, 2004, 2:18:50 PM6/12/04
to
tom_u...@hotmail.com (tom_usenet) writes:

[...]

| However, it is reasonably easy to get
| right I think, I think you just need:

People at GNU libstdc++ would most welcome your easy patch in getting
that corrected.

--
Gabriel Dos Reis
g...@cs.tamu.edu
Texas A&M University -- Computer Science Department
301, Bright Building -- College Station, TX 77843-3112

---

Gabriel Dos Reis

unread,
Jun 12, 2004, 2:18:54 PM6/12/04
to
com...@panix.com (Greg Comeau) writes:

[...]

| whereas only DD is in this case:
|
| #include <cstdio>
|
| int main()
| {
| printf("CC\n");
| std::printf("DD\n");
|
| return 0;
| }
|
| CC is allowed but not guaranteed.

No, it is not allowed. A <cxxx> header cannot include a <xxx.h> header.

--
Gabriel Dos Reis
g...@cs.tamu.edu
Texas A&M University -- Computer Science Department
301, Bright Building -- College Station, TX 77843-3112

---

Gennaro Prota

unread,
Jun 12, 2004, 2:19:26 PM6/12/04
to
com...@panix.com (Greg Comeau) wrote in message news:<cacahp$r20$1...@panix1.panix.com>...


> whereas only DD is in this case:
>
> #include <cstdio>
>
> int main()
> {
> printf("CC\n");
> std::printf("DD\n");
>
> return 0;
> }
>
> CC is allowed but not guaranteed.

Are you sure CC is allowed? The standard distinguishes beetween "C
headers" (.h form) and "C++ headers". 17.4.4.1/1 seems to imply that a
C++ header cannot include a C header. Thus, for printf to be in the
global namespace it should be directly declared there in a *C++
header*, which I think is not the intent.

--
Genny.

Prateek R Karandikar

unread,
Jun 12, 2004, 2:20:50 PM6/12/04
to
But is it really so difficult for implementors to put declarations in
std and *not* in global for the C++ style headers. Wouldn't it be as
simple as:

namespace std
{
//stuff
}

The fact that so many implementations are not complying to the
Standard means that it must be difficult to prevent the names from
being available directly in the global namespace. Why is it so
difficult?

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
To iterate is human, to recurse divine.
-L. Peter Deutsch
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

P.J. Plauger

unread,
Jun 12, 2004, 9:26:32 PM6/12/04
to
"Prateek R Karandikar" <kprat...@yahoo.com> wrote in message
news:607f883e.04061...@posting.google.com...

> But is it really so difficult for implementors to put declarations in
> std and *not* in global for the C++ style headers.

Yes.

> Wouldn't it be as
> simple as:
>
> namespace std
> {
> //stuff
> }

No. Take a look at a typical Standard C header and then decide
just what "//stuff" should look like. You can copy the magic
code, but then you have two copies to keep in sync. And *you*
may not have much to say about what happens to the C headers,
or when.

> The fact that so many implementations are not complying to the
> Standard means that it must be difficult to prevent the names from
> being available directly in the global namespace. Why is it so
> difficult?

See above. Then think about the rest of the problem -- ensuring
that the Standard C headers first define names in namespace std,
then import them to the global namespace.

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

---

Gennaro Prota

unread,
Jun 13, 2004, 9:24:50 AM6/13/04
to
On Sun, 13 Jun 2004 01:26:32 +0000 (UTC), p...@dinkumware.com ("P.J.
Plauger") wrote:

>See above. Then think about the rest of the problem -- ensuring
>that the Standard C headers first define names in namespace std,
>then import them to the global namespace.

I'm not a fan of the choice that <name.h> headers also make names
available in namespace std but... would it be difficult for the
compiler to do the magic? Example: the library implementor writes
*one* <string.h> with all declarations in the global namespace. The
compiler, when in C++ mode, knows that all the names must be first put
in ::std (as if declared there) and then imported. A <cstring> file
doesn't exist; the compiler simply reads <string.h> and does the first
part of the job above. Am I crazy? :)

P.S.: I don't like this technique. So I'm not sure of my craziness ;)


Genny.

Prateek R Karandikar

unread,
Jun 13, 2004, 3:12:31 PM6/13/04
to
Is it necessary that one of <cstdio> and <stdio.h> should #include the
other? Why can't they just be 2 independent headers, with almost
identical code? The duplication and keeping in sync can be automated.

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
To iterate is human, to recurse divine.
-L. Peter Deutsch
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

---

Greg Comeau

unread,
Jun 13, 2004, 4:36:31 PM6/13/04
to
In article <m3wu2en...@merlin.cs.tamu.edu>,

Gabriel Dos Reis <g...@cs.tamu.edu> wrote:
>com...@panix.com (Greg Comeau) writes:
>[...]
>| whereas only DD is in this case:
>|
>| #include <cstdio>
>|
>| int main()
>| {
>| printf("CC\n");
>| std::printf("DD\n");
>|
>| return 0;
>| }
>|
>| CC is allowed but not guaranteed.
>
>No, it is not allowed. A <cxxx> header cannot include a <xxx.h> header.

My understanding came from members of the LWG years ago because
at that time I was unclear on the standard's words and the intents
of the [LWG part of the] committee wrt this (if I can recall
correctly, I was ignoring the words in appendix D I think it was).

Are there specific clauses that you believe prohibit it?
Or do you believe it's not allowed by virtue of falling out from
some larger concept/constraint/whatever? Or from something
in the LWG issues list?


--
Greg Comeau / Comeau C++ 4.3.3, for C++03 core language support
Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?

---

P.J. Plauger

unread,
Jun 13, 2004, 4:37:45 PM6/13/04
to
"Gennaro Prota" <gennar...@yahoo.com> wrote in message
news:bg9oc0157c7a2jhnm...@4ax.com...

> On Sun, 13 Jun 2004 01:26:32 +0000 (UTC), p...@dinkumware.com ("P.J.
> Plauger") wrote:
>
> >See above. Then think about the rest of the problem -- ensuring
> >that the Standard C headers first define names in namespace std,
> >then import them to the global namespace.
>
> I'm not a fan of the choice that <name.h> headers also make names
> available in namespace std but... would it be difficult for the
> compiler to do the magic? Example: the library implementor writes
> *one* <string.h> with all declarations in the global namespace. The
> compiler, when in C++ mode, knows that all the names must be first put
> in ::std (as if declared there) and then imported. A <cstring> file
> doesn't exist; the compiler simply reads <string.h> and does the first
> part of the job above. Am I crazy? :)
>
> P.S.: I don't like this technique. So I'm not sure of my craziness ;)

Yes, you're crazy. You have to understand that at least three
political groups are involved in making C++ work on a given
platform:

1) the people who support the compiler

2) the people who support the C++ library

3) the people who support the C library

There are very real limits to how much any one of these groups
can dictate to the others. What you describe would involve a
truly unholy interaction among all three. The C++ library
people would have to produce a *precise* recipe for what
C names should be mapped, and how. The compiler people would
then have to turn that into the magic you describe. And, oh
yes, the C people would be obliged to add all sorts of overloads,
and accept an assortment of constraints, that they have so far
disdained.

Every time a standard specifies a library facility that requires
compiler magic to work properly, it causes a 3-5 year delay in
widespread conformance, it invariably creates unexpected
dialects, and it increases the number of bugs. Here be dragons.

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

---

P.J. Plauger

unread,
Jun 13, 2004, 8:58:11 PM6/13/04
to
"Prateek R Karandikar" <kprat...@yahoo.com> wrote in message
news:607f883e.04061...@posting.google.com...

> Is it necessary that one of <cstdio> and <stdio.h> should #include the


> other? Why can't they just be 2 independent headers, with almost
> identical code? The duplication and keeping in sync can be automated.

I'm sure it can -- go ahead and try.

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

---

Greg Comeau

unread,
Jun 14, 2004, 12:15:38 PM6/14/04
to
In article <607f883e.04061...@posting.google.com>,

Prateek R Karandikar <kprat...@yahoo.com> wrote:
>Is it necessary that one of <cstdio> and <stdio.h> should #include the
>other?

Not literally, if that's what you mean.

>Why can't they just be 2 independent headers, with almost
>identical code?

They can.

I prefer to think the standard describes behaviors with
sufficient wiggle room.

>The duplication and keeping in sync can be automated.

Maybe.


--
Greg Comeau / Comeau C++ 4.3.3, for C++03 core language support
Comeau C/C++ ONLINE ==> http://www.comeaucomputing.com/tryitout
World Class Compilers: Breathtaking C++, Amazing C99, Fabulous C90.
Comeau C/C++ with Dinkumware's Libraries... Have you tried it?

---

Gabriel Dos Reis

unread,
Jun 14, 2004, 1:52:10 PM6/14/04
to
com...@panix.com (Greg Comeau) writes:

| In article <m3wu2en...@merlin.cs.tamu.edu>,
| Gabriel Dos Reis <g...@cs.tamu.edu> wrote:
| >com...@panix.com (Greg Comeau) writes:
| >[...]
| >| whereas only DD is in this case:
| >|
| >| #include <cstdio>
| >|
| >| int main()
| >| {
| >| printf("CC\n");
| >| std::printf("DD\n");
| >|
| >| return 0;
| >| }
| >|
| >| CC is allowed but not guaranteed.
| >
| >No, it is not allowed. A <cxxx> header cannot include a <xxx.h> header.
|
| My understanding came from members of the LWG years ago because
| at that time I was unclear on the standard's words and the intents
| of the [LWG part of the] committee wrt this (if I can recall
| correctly, I was ignoring the words in appendix D I think it was).

This issue has been discussed over and over, among the library
implementers and LWG members. Each time, we went through this, the
outcome is that one I described. Look at the answers given by other
LWG members and library implementers in this thread.

| Are there specific clauses that you believe prohibit it?
| Or do you believe it's not allowed by virtue of falling out from
| some larger concept/constraint/whatever? Or from something
| in the LWG issues list?

The wordings are essentially those from D.5/2

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 also placed within the namespace scope
of the namespace std and is followed by an explicit
using-declaration (7.3.3).

The note (albeit non-normative) D.5/3 clarifies that <cxxx> provides
their declarations and definitions within namespace std. That
excludes a (using-)declaration at global scope. Library clause
17.4.1.2/4 even makes clearer:

Except as noted in clauses 18 through 27, the contents of each
header cname shall be the same as that of the corresponding header
name.h, as specified in ISO/IEC 9899:1990 Programming Languages C
(Clause 7), or ISO/IEC:1990 Programming Languages C AMENDMENT 1: C
Integrity, (Clause 7), as appropriate, as if by inclusion. In the C
+ + Standard Library, however, the declarations and definitions
(except for names which are defined as macros in C) are within
namespace scope (3.3.5) of the namespace std.

Interestingly, 17.4.4.1/3 is much more presciptive:

Header inclusion is limited as follows:
-- The C headers ( .h form, described in Annex D, D.5) shall include
only their corresponding C + + header, as described above
(17.4.1.2).

--
Gabriel Dos Reis
g...@cs.tamu.edu
Texas A&M University -- Computer Science Department
301, Bright Building -- College Station, TX 77843-3112

---

Gabriel Dos Reis

unread,
Jun 14, 2004, 1:52:14 PM6/14/04
to
gennar...@yahoo.com (Gennaro Prota) writes:

| com...@panix.com (Greg Comeau) wrote in message news:<cacahp$r20$1...@panix1.panix.com>...
|
| > whereas only DD is in this case:
| >
| > #include <cstdio>
| >
| > int main()
| > {
| > printf("CC\n");
| > std::printf("DD\n");
| >
| > return 0;
| > }
| >
| > CC is allowed but not guaranteed.
|
| Are you sure CC is allowed?

No, it is not.

| The standard distinguishes beetween "C
| headers" (.h form) and "C++ headers". 17.4.4.1/1 seems to imply that a
| C++ header cannot include a C header.

Indeed.

--
Gabriel Dos Reis
g...@cs.tamu.edu
Texas A&M University -- Computer Science Department
301, Bright Building -- College Station, TX 77843-3112

---

Dietmar Kuehl

unread,
Jun 15, 2004, 1:58:03 PM6/15/04
to
tom_u...@hotmail.com (tom_usenet) wrote:
> However, it is reasonably easy to get
> right I think, I think you just need:

You think wrong. The problem is that normally the C library is not at all
controlled by the C++ library implementation. This effectively means that
the standard C header contain declarations which are not part of the
standard C or standard C++ library. This far you can get things to work
(well, mostly, at least; I encountered problems with certain macro
definitions on all implementations I tried). Unfortunately, things fail
miserably if someone tries to include a non-standard header.
--
<mailto:dietma...@yahoo.com> <http://www.dietmar-kuehl.de/>
<http://www.contendix.com> - Software Development & Consulting

Gennaro Prota

unread,
Jun 16, 2004, 2:50:43 AM6/16/04
to
g...@cs.tamu.edu (Gabriel Dos Reis) wrote in message news:<m3d644c...@merlin.cs.tamu.edu>...

> gennar...@yahoo.com (Gennaro Prota) writes:
> | The standard distinguishes beetween "C
> | headers" (.h form) and "C++ headers". 17.4.4.1/1 seems to imply that a
> | C++ header cannot include a C header.
>
> Indeed.

Thanks. I think that should be said explicitly, though (the paragraph
just says a C++ header may include other C++ headers; that doesn't
carry as a consequence that it can't include C headers. Indeed, I had
to ask.)

While we are at it, I seize the occasion to also ask about the
mysterious (for me) note 170. What does it mean? The first time I read
it I interpreted it as saying that if a header needs a definition it
must include the *full* header containing that definition (not a
part). I see however that a lot of libraries (including libstdc++)
don't do that; for instance libstdc++ has a bits/ subdirectory where
small "pieces" of headers are stored and included as needed. So either
they are ignoring note 170 or the note itself has a meaning I don't
understand (of course it's non-normative, but that's not the point).

--
Genny.

Pete Becker

unread,
Jun 16, 2004, 1:45:12 PM6/16/04
to
Gennaro Prota wrote:
>
> While we are at it, I seize the occasion to also ask about the
> mysterious (for me) note 170. What does it mean? The first time I read
> it I interpreted it as saying that if a header needs a definition it
> must include the *full* header containing that definition (not a
> part). I see however that a lot of libraries (including libstdc++)
> don't do that; for instance libstdc++ has a bits/ subdirectory where
> small "pieces" of headers are stored and included as needed. So either
> they are ignoring note 170 or the note itself has a meaning I don't
> understand (of course it's non-normative, but that's not the point).
>

No, that is the point: since footnotes aren't normative, it's okay to
ignore them. But that's not really what's happening. That footnote tries
to explain why C++ headers are allowed to include other headers, since C
doesn't permit that. The long form of the explanation is that many C++
things can't be forward declared easily, so it's often necessary to
include another header that actually defines them. The short form of the
explanation is that headers "must" include other headers.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

Graeme Prentice

unread,
Jun 16, 2004, 8:11:40 PM6/16/04
to
On Wed, 16 Jun 2004 17:45:12 +0000 (UTC), Pete Becker wrote:

>>
>
>No, that is the point: since footnotes aren't normative, it's okay to
>ignore them.

So does "normative" mean things that are binding on a conforming
implementation and anything else is just "commentary"?

Does the statement in 17.3.1.1/2 apply to the entire standard or just
the library chapters?

Where is it defined that footnotes are non-normative and where is it
defined what a note is?

What does 1.5/6 mean by "Examples and notes may be nested."?

Graeme

Pete Becker

unread,
Jun 16, 2004, 8:48:17 PM6/16/04
to
Graeme Prentice wrote:
>
> On Wed, 16 Jun 2004 17:45:12 +0000 (UTC), Pete Becker wrote:
>
> >>
> >
> >No, that is the point: since footnotes aren't normative, it's okay to
> >ignore them.
>
> So does "normative" mean things that are binding on a conforming
> implementation and anything else is just "commentary"?

Yup. Also known as "non-normative."

>
> Does the statement in 17.3.1.1/2 apply to the entire standard or just
> the library chapters?

The first rule of statutory construction is "begin at the beginning." In
particular, 17.1.

>
> Where is it defined that footnotes are non-normative and where is it
> defined what a note is?

ISO rules. (The things labeled "Note(s)", as mentioned in 17.3.1.1/2,
are not "notes" within the meaning of the ISO rules; we need to change
that label)

>
> What does 1.5/6 mean by "Examples and notes may be nested."?
>

It means that notes may include examples, examples may include notes,
notes may include other notes, and examples may include other examples
(although I don't think the standard actually does that last one).

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

---

Gennaro Prota

unread,
Jun 17, 2004, 1:16:46 PM6/17/04
to
peteb...@acm.org (Pete Becker) wrote in message news:<40D043A7...@acm.org>...


> No, that is the point: since footnotes aren't normative, it's okay to
> ignore them. But that's not really what's happening. That footnote tries
> to explain why C++ headers are allowed to include other headers, since C
> doesn't permit that. The long form of the explanation is that many C++
> things can't be forward declared easily, so it's often necessary to
> include another header that actually defines them. The short form of the
> explanation is that headers "must" include other headers.

Hmm... there seems to be a misunderstanding. Let me make an example:
suppose a standard header <xyz> needs the definition of basic_ostream.
If I know that it needs that definition can I be sure that including
<xyz> also makes <ostream>'s non-member functions available? My guess
is not; i.e.: the implememtation could put the definition of
basic_ostream in its own file, let's say basic_ostream_def.hpp, and
include just that (the same file would likely be included by <ostream>
itself). The footnote instead seems to say that <dummy> must include
<ostream>, because it talks about *header* which contains the needed
definition (and, of course, basic_ostream_def.hpp is not a header in
the standard sense).

--
Genny.

Pete Becker

unread,
Jun 17, 2004, 3:08:22 PM6/17/04
to
Gennaro Prota wrote:
>
> Hmm... there seems to be a misunderstanding. Let me make an example:
> suppose a standard header <xyz> needs the definition of basic_ostream.
> If I know that it needs that definition can I be sure that including
> <xyz> also makes <ostream>'s non-member functions available? My guess
> is not;

Your guess is right. To use a name from the standard library the
standard says that you must include the header that the standard says
defines that name. In practice you often don't really need to do that,
but that's an accident, not a requirement.

> i.e.: the implememtation could put the definition of
> basic_ostream in its own file, let's say basic_ostream_def.hpp, and
> include just that (the same file would likely be included by <ostream>
> itself). The footnote instead seems to say that <dummy> must include
> <ostream>, because it talks about *header* which contains the needed
> definition (and, of course, basic_ostream_def.hpp is not a header in
> the standard sense).
>

The "must" in the footnote is an unfortunate choice of word, which was
my point earlier. In this context it means that, as an implmentation
detail, headers often need to include other headers. Nothing more.

--

Pete Becker
Dinkumware, Ltd. (http://www.dinkumware.com)

---

John Potter

unread,
Jun 17, 2004, 7:36:22 PM6/17/04
to
On Thu, 17 Jun 2004 00:11:40 +0000 (UTC), gpr...@hotmail.com (Graeme
Prentice) wrote:

> Does the statement in 17.3.1.1/2 apply to the entire standard or just
> the library chapters?

All of 17.3 is informative and is non-binding on anything. :)

John

Gennaro Prota

unread,
Jun 19, 2004, 7:31:15 PM6/19/04
to
On Thu, 17 Jun 2004 19:08:22 +0000 (UTC), peteb...@acm.org (Pete
Becker) wrote:

>The "must" in the footnote is an unfortunate choice of word, which was
>my point earlier. In this context it means that, as an implmentation
>detail, headers often need to include other headers. Nothing more.

Thanks. So it's basically a mistaken note. BTW, I would say that an
implementation never *needs* to include a header. Exactly because it
is "the implementation" it may well include a piece of it. It's rather
normal users, instead, who don't have this luxury and can only access
standard library facilities through those atomic blocks they call
headers.


--
Genny.

0 new messages