WG 14 Document number | N1308 |
WG 21 Document number | N2604=08-0114 |
Date | 2008-04-25 |
Projects | Programming Languages C & C++ |
Reference | ISO/IEC IS 9899:1999 |
Reference | ISO/IEC IS 14882:2003(E) |
Reply to | Nick Stoughton |
USENIX Association | |
nick@usenix.org |
SC22 WG14 N1257 describes an inconsistency in the wording for <errno.h>. In p1, <errno.h> defines several macros. In p2 "The macros are ... errno". But later in p2 "It is unspecified whether errno is a macro or an identifier declared with external linkage." So is errno a macro or not?
If we consider existing practice very old implementations, and some current embedded implmentations, have errno as a simple integer variable. On the other hand, any implementation that has support for some form of multi-threading implements errno as a macro, expanding into a different modifiable lvalue for each thread. It could also, potentially, be implemented using some form of thread local storage.
N1257 took these factors into consideration, and proposed wording that removed the ambiguity but preserved all existing implementations (no quiet changes). The paper was considered during the Kona meeting, and N1270 (the Kona minutes) stated
C++ is requiring that they be macros. It would not be a bad thing if we did likewise. Make it required that errno is a macro, rather than unspecified.
The current wording in SC22 WG21 N2588 (the C++ Working Draft), states:
The header <cerrno> is described in (Table 29). Its contents are the same as the POSIX header <errno.h>, except that errno shall be defined as a macro. [ Note: The intent is to remain in close alignment with the POSIX standard. -end note ]
In turn, POSIX defines errno as
The <errno.h> header shall provide a declaration or definition for errno. The symbol errno shall expand to a modifiable lvalue of type int. It is unspecified whether errno is a macro or an identifier declared with external linkage. If a macro definition is suppressed in order to access an actual object, or a program defines an identifier with the name errno, the behavior is undefined.
These are the same words proposed in WG14 N1257. The stated goal (in a note) of C++ is to align with POSIX, but POSIX does not require that errno be a macro.
For these reasons, this paper, while requested by WG 14, is being submitted to both WG14 and WG21 and contains proposed changes to the C++ working draft. It also seeks to try to handle any potential conflict between C++ and POSIX over the content of the POSIX header <errno.h>.
19.3 Error numbers [errno]
The header <cerrno> is described in (Table 29).
Its contents are the same asaligned with
the POSIX header <errno.h>, except that
errno shall be defined as a macro; any
conflict between the requirements described here and the ISO POSIX standard is unintentional. This
standard defers to the POSIX standard.
[ Note: The intent is to remain in close alignment with the POSIX standard. -end
note ]
Table 29: Header
The <cerrno> header also provides a declaration or definition for errno. The symbol
errno shall expand to a modifiable lvalue of type int. It is unspecified
whether errno is a macro or an identifier declared with external
linkage. If a macro definition is suppressed in order to access an
actual object, or a program defines an identifier with the name errno,
the behavior is undefined.
The value of errno is zero at program start-up, but is never set to zero
by any library function. The value of errno may be set to nonzero
by a library function call whether or not there is an error, provided
the use of errno is not documented in the description of the function
in this International Standard.
The following is drawn from the wording suggested in WG14 N1257, and is repeated here for
clarity with minor editorial changes. In addition, this is now presented as change marked
differences (using strikethrough etc)
to make it easier to understand the change.
In 7.5, change para 2 to read:
The macros are
SEE ALSO: ISO C subclause 7.1.4, 7.2, Amendment 1 subclause 4.3.
Type Name(s) Macros: ECONNREFUSED EIO ENODEV ENOTEMPTY ERANGE E2BIG ECONNRESET EISCONN ENOENT ENOTRECOVERABLE EROFS EACCES EDEADLK EISDIR ENOEXEC ENOTSOCK ESPIPE EADDRINUSE EDESTADDRREQ ELOOP ENOLCK ENOTSUP ESRCH EADDRNOTAVAIL EDOM EMFILE ENOLINK ENOTTY ETIME EAFNOSUPPORT EEXIST EMLINK ENOMEM ENXIO ETIMEDOUT EAGAIN EFAULT EMSGSIZE ENOMSG EOPNOTSUPP ETXTBSY EALREADY EFBIG ENAMETOOLONG ENOPROTOOPT EOVERFLOW EWOULDBLOCK EBADF EHOSTUNREACH ENETDOWN ENOSPC EOWNERDEAD EXDEV EBADMSG EIDRM ENETRESET ENOSR EPERM errno EBUSY EILSEQ ENETUNREACH ENOSTR EPIPE ECANCELED EINPROGRESS ENFILE ENOSYS EPROTO ECHILD EINTR ENOBUFS ENOTCONN EPROTONOSUPPORT ECONNABORTED EINVAL ENODATA ENOTDIR EPROTOTYPE Proposed wording for C
EDOM
EILSEQ
ERANGE
which expand to integer constant expressions with type int, distinct positive values, and
which are suitable for use in #if preprocessing directives.; and
errno
which
The <errno.h> header also provides a declaration or definition for errno. The symbol
errno
expands to a modifiable lvalue175) that has type int, the value of which is set to a
positive error number by several library functions. It is unspecified whether errno is a
macro or an identifier declared with external linkage. If a macro definition is suppressed
in order to access an actual object, or a program defines an identifier with the name
errno, the behavior is undefined.