Topic: errno - Standard incosistency?
Author: Ron Natalie <ron@sensor.com>
Date: Sun, 18 Mar 2001 18:32:06 GMT Raw View
"James Kuyper Jr." wrote:
> Note that C99 requires only that errno expand to a modifiable lvalue,
> and specifically gives an expression similar to that one as an example
> of how a "modifiable lvalue" can be something more complicated than a
> simple object name.
>
Yes, but the sticky point is that C standards allow errno to also
not be a macro.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Dima Volodin <dvv@dvv.org>
Date: Mon, 19 Mar 2001 00:09:45 GMT Raw View
Ron Natalie wrote:
>
> Personally, a quick survey of the implementations I have here show it as an
> identifier. For example SUN has this:
> namespace std { extern "C" { extern int errno; } }
_Very_ bad idea. It can lead to a situation where std::errno will work
in some supposedly conforming implementations and won't work in others.
And this is a direct consequence of the described inconsistency, isn't
it?
Dima
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Dima Volodin <dvv@dvv.org>
Date: Mon, 19 Mar 2001 00:09:25 GMT Raw View
"James Kuyper Jr." wrote:
>
> Dima Volodin wrote:
> >
> > Ron Natalie wrote:
> > >
> > > Personally, a quick survey of the implementations I have here show it as an
> > > identifier. For example SUN has this:
> > > namespace std { extern "C" { extern int errno; } }
> >
> > I wish I had Sun's C++ handy - with the include files available to me
> > and when I do multithreading, I hit things like this:
> >
> > #define errno (*(___errno()))
> >
> > and you certainly don't want to allow std::errno if you don't ban macros
> > like this one.
>
> Note that C99 requires only that errno expand to a modifiable lvalue,
> and specifically gives an expression similar to that one as an example
> of how a "modifiable lvalue" can be something more complicated than a
> simple object name.
Which basically means that an implementation _can not_ do
namespace std { extern "C" { extern int errno; } }
Right?
Dima
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: Mon, 19 Mar 2001 12:28:39 GMT Raw View
Dima Volodin wrote:
>
> Ron Natalie wrote:
> >
> > Personally, a quick survey of the implementations I have here show it as an
> > identifier. For example SUN has this:
> > namespace std { extern "C" { extern int errno; } }
>
> _Very_ bad idea. It can lead to a situation where std::errno will work
> in some supposedly conforming implementations and won't work in others.
Could you explain what you mean by "won't work"? Give a concrete
example. I can't see any problems with that definition. If a given
program doesn't work with this definition, it's probably defective code,
not a non-conforming definition of errno.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Dima Volodin <dvv@dvv.org>
Date: Mon, 19 Mar 2001 18:30:18 GMT Raw View
"James Kuyper Jr." wrote:
>
> Dima Volodin wrote:
> >
> > Ron Natalie wrote:
> > >
> > > Personally, a quick survey of the implementations I have here show it as an
> > > identifier. For example SUN has this:
> > > namespace std { extern "C" { extern int errno; } }
> >
> > _Very_ bad idea. It can lead to a situation where std::errno will work
> > in some supposedly conforming implementations and won't work in others.
>
> Could you explain what you mean by "won't work"? Give a concrete
> example. I can't see any problems with that definition. If a given
> program doesn't work with this definition, it's probably defective code,
> not a non-conforming definition of errno.
With a definition like this, one has to use either std::errno or using
namespace std or the like, and it won't work in other implementations
where errno is defined as a macro. To illustrate:
// ee.cc
#include <cerrno>
#include <iostream>
int
main ()
{
std::cout << std::errno << std::endl;
}
51_dv@brain: g++ ee.cc
52_dv@brain: g++ -pthreads ee.cc
ee.cc: In function `int main()':
ee.cc:7: parse error before `('
Without -pthreads, the following declaration is used:
extern int errno; // in std
with -pthreads, it's defined as
#define errno (*(___errno()))
with extern "C" placed appropriately in both cases.
So the Standard should require that errno is either a macro or a name in
the std namespace without giving any choice to implementations. Either
alternative is viable (with the latter requiring a bit more work to do
for the implementers), but there should be only one allowed by the
Standard.
BTW, the comp.std.c++ FAQ implies that a DR about this inconsistency
have been filed, but I couldn't find anything about this DR either.
Dima
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Steve Clamage <stephen.clamage@sun.com>
Date: Thu, 22 Mar 2001 00:07:33 GMT Raw View
Dima Volodin wrote:
>
> Per 17.4.1.2/5, errno should be defined as a macro, but footnote 166 in
> 17.4.3.1.3/1 refers to errno as if it were a name of an object with
> external linkage. Is it a real inconsistency or am I just missing
> something?
There is an inconsistency in the standard about whether errno is a macro:
17.4.1.2 says in a note that errno must be macro in C. (false, see below)
17.4.3.3 footnote 166 says errno is reserved as an external name. (true)
19.3 simply lists errno as a macro (by what reasoning?) and goes
on to say that the contents of of C++ <errno.h> are the
same as in C, begging the question.
C.2, table 95 lists errno as a macro, without comment.
The C standard says that it is unspecified whether errno is a macro or
an identifier with external linkage. "Unspecified" means that the
implementation doesn't have to tell you which, and need not be
consistent. Errno must in any case expand to a modifiable lvalue
expression of type int.
The latitude granted allows an implementation to declare it as
extern int errno; // single global variable
for single-threaded programs and as
int* __errno(); // returns ptr to a thread-local errno
#define errno (*(__errno()))
for multi-threaded programs.
Either definition of errno satisfies the C requirements, and allows
you to write
int i = errno;
errno = 42;
But in C++ we have an additional problem: if errno is an identifier with
external linkage, it must be in namespace std, and you can access it as
"std::errno". But if errno is a macro, you cannot necessarily access it
as std::errno. For example, given the multi-threaded example above,
std::errno expands to
std::(*(__errno()))
which is not valid syntax.
Two possible resolutions to the inconsistencies in the C++ standard:
1. errno is in the global namespace, not in namespace std.
2. errno must be a macro, in which case you would never put a namespace
qualifier on it.
#2 does not cause any problems, because even when errno is a global
variable spelled "errno", the implementation can still provide the
macro definition
#define errno errno
The rules for macro replacement do not allow recursion, so errno just
becomes errno when expanded.
This issue was presented to the C++ committee, but fell into a crack
without being resolved or put onto an Issues List. I'm glad you posted
this question, because now we can see that the issue gets resolved.
--
Steve Clamage, stephen.clamage@sun.com
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Ron Natalie <ron@spamcop.net>
Date: Thu, 22 Mar 2001 01:13:48 GMT Raw View
Steve Clamage wrote:
>=20
> Dima Volodin wrote:
> >
> > Per 17.4.1.2/5, errno should be defined as a macro, but footnote 166 =
in
> > 17.4.3.1.3/1 refers to errno as if it were a name of an object with
> > external linkage. Is it a real inconsistency or am I just missing
> > something?
>=20
> There is an inconsistency in the standard about whether errno is a macr=
o:
>=20
> 17.4.1.2 says in a note that errno must be macro in C. (false, see belo=
w)
17.4.1.2 is further wrong in that it implies that errno is a function
Names which are defined as macros in C shall be defined as macros
in the C++ Standard Library, even if C grants license for implementation
as functions. [Note: the names defined as macros in C include the follow=
ing:
assert, errno, offsetof, setjmp, va_arg, va_end, and va_start. =97end no=
te]
which it isn't. (Furthermore the TROFF to PDF conversion seem sto have s=
ucked up
an spurious hypen in the word "following" above.]
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: scott douglass <sdouglass@arm.com>
Date: Fri, 23 Mar 2001 20:42:10 GMT Raw View
Steve Clamage wrote:
>Two possible resolutions to the inconsistencies in the C++ standard:
>
>1. errno is in the global namespace, not in namespace std.
I don't think that is sufficient because the following wouldn't work (if
errno was a macro that didn't begin with an identifier):
::errno = 0;
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Dima Volodin <dvv@dvv.org>
Date: Fri, 16 Mar 2001 21:43:32 GMT Raw View
Ron Natalie wrote:
>
> Personally, a quick survey of the implementations I have here show it as an
> identifier. For example SUN has this:
> namespace std { extern "C" { extern int errno; } }
I wish I had Sun's C++ handy - with the include files available to me
and when I do multithreading, I hit things like this:
#define errno (*(___errno()))
and you certainly don't want to allow std::errno if you don't ban macros
like this one.
Cheers!
Dima
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Dima Volodin <dvv@dvv.org>
Date: Fri, 16 Mar 2001 19:42:24 GMT Raw View
Per 17.4.1.2/5, errno should be defined as a macro, but footnote 166 in
17.4.3.1.3/1 refers to errno as if it were a name of an object with
external linkage. Is it a real inconsistency or am I just missing
something?
Thanks!
Dima
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Ron Natalie <ron@spamcop.net>
Date: Fri, 16 Mar 2001 20:11:38 GMT Raw View
Dima Volodin wrote:
>
> Per 17.4.1.2/5, errno should be defined as a macro, but footnote 166 in
> 17.4.3.1.3/1 refers to errno as if it were a name of an object with
> external linkage. Is it a real inconsistency or am I just missing
> something?
It's an inconsistancy, and that's not all that's screwy.
It's a little tough to follow, but the C standard doesn't require errno
to be a macro. It allows it either to be a macro expanding to a modifiable
l-value or to be the external identifier name itself. (C90 section 7.1.4,
but the same in C99 section 7.5).
17.4.1.2/5 is a bit confusing as a result. It says "Names which are defined
as macros in C shall be defined as macros in the C++ Standard Library, even if C
grants license for implementation as functions." Well, C grants license for
it not to be a macro, but not to be a function.
So we have to ask, can errno be an identifier rather than a macro in C++?
If not, then 17.4.1.2/5 needs to use "identifier" rather than "functions"
in the prophibition.
In either case footnote 166 needs work. In the case when errno can be an
identifier it probably needs to state "when errno is an identifier." In the
case errno can't be an identifier, then the footnote is nonsense.
Personally, a quick survey of the implementations I have here show it as an
identifier. For example SUN has this:
namespace std { extern "C" { extern int errno; } }
I can't find anything in the defects list on this, you win a cookie.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: Dima Volodin <dvv@dvv.org>
Date: 16 Mar 2001 22:55:55 -0500 Raw View
Per 17.4.1.2/5, errno should be defined as a macro, but footnote 166 in
17.4.3.1.3/1 refers to errno as if it were a name of an object with
external linkage. Is it a real inconsistency or am I just missing
something?
Thanks!
Dima
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]
Author: "James Kuyper Jr." <kuyper@wizard.net>
Date: Sat, 17 Mar 2001 08:31:32 GMT Raw View
Dima Volodin wrote:
>
> Ron Natalie wrote:
> >
> > Personally, a quick survey of the implementations I have here show it as an
> > identifier. For example SUN has this:
> > namespace std { extern "C" { extern int errno; } }
>
> I wish I had Sun's C++ handy - with the include files available to me
> and when I do multithreading, I hit things like this:
>
> #define errno (*(___errno()))
>
> and you certainly don't want to allow std::errno if you don't ban macros
> like this one.
Note that C99 requires only that errno expand to a modifiable lvalue,
and specifically gives an expression similar to that one as an example
of how a "modifiable lvalue" can be something more complicated than a
simple object name.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://www.research.att.com/~austern/csc/faq.html ]