Title
Is errno a macro?
Status
cd1
Section
[headers][errno]
Submitter
Steve Clamage

Created on 2001-03-21.00:00:00 last changed 172 months ago

Messages

Date: 2010-10-21.18:28:33

[ Curaçao: additional rationale added. ]

Date: 2010-10-21.18:28:33

Rationale:

C++ must not leave it up to the implementation to decide whether or not a name is a macro; it must explicitly specify exactly which names are required to be macros. The only one that really works is for it to be a macro.

Date: 2010-10-21.18:28:33

Proposed resolution:

Change the Note in section 17.4.1.2p5 from

Note: the names defined as macros in C include the following: assert, errno, offsetof, setjmp, va_arg, va_end, and va_start.

to

Note: the names defined as macros in C include the following: assert, offsetof, setjmp, va_arg, va_end, and va_start.

In section 19.3, change paragraph 2 from

The contents are the same as the Standard C library header <errno.h>.

to

The contents are the same as the Standard C library header <errno.h>, except that errno shall be defined as a macro.

Date: 2010-10-21.18:28:33

[ This issue was first raised in 1999, but it slipped through the cracks. ]

Date: 2001-03-21.00:00:00

Exactly how should errno be declared in a conforming C++ header?

The C standard says in 7.1.4 that it is unspecified whether errno is a macro or an identifier with external linkage. In some implementations it can be either, depending on compile-time options. (E.g., on Solaris in multi-threading mode, errno is a macro that expands to a function call, but is an extern int otherwise. "Unspecified" allows such variability.)

The C++ standard:

  • 17.4.1.2 says in a note that errno must be macro in C. (false)
  • 17.4.3.1.3 footnote 166 says errno is reserved as an external name (true), and implies that it is an identifier.
  • 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.

I find no other references to errno.

We should either explicitly say that errno must be a macro, even though it need not be a macro in C, or else explicitly leave it unspecified. We also need to say something about namespace std. A user who includes <cerrno> needs to know whether to write errno, or ::errno, or std::errno, or else <cerrno> is useless.

Two acceptable fixes:

  • errno must be a macro. This is trivially satisfied by adding
      #define errno (::std::errno)
    to the headers if errno is not already a macro. You then always write errno without any scope qualification, and it always expands to a correct reference. Since it is always a macro, you know to avoid using errno as a local identifer.

  • errno is in the global namespace. This fix is inferior, because ::errno is not guaranteed to be well-formed.

History
Date User Action Args
2010-10-21 18:28:33adminsetmessages: + msg2199
2010-10-21 18:28:33adminsetmessages: + msg2198
2010-10-21 18:28:33adminsetmessages: + msg2197
2010-10-21 18:28:33adminsetmessages: + msg2196
2001-03-21 00:00:00admincreate