[3/8] sys/types.h: Don’t define u_intN_t or register_t unless __USE_MISC.

Message ID adf04a2ec1fb975659126f31ef9b547f409ccd7d.1552315664.git.zackw@panix.com
State Superseded
Headers

Commit Message

Zack Weinberg March 11, 2019, 2:59 p.m. UTC
  sys/types.h unconditionally defines u_int8_t, u_int16_t, u_int32_t,
u_int64_t, and register_t.  These are not part of any standard.  The
u_intXX_t types are superseded by C99’s uintXX_t types (defined in
stdint.h).  I’m not aware of a standardized exact equivalent of
register_t, but also I’ve never seen anyone use it for anything.
I could be persuaded to leave that one alone.

sys/types.h also unconditionally defines int8_t, int16_t, int32_t, and
int64_t, which are the same as the C99 exact-width signed types in
stdint.h.  POSIX doesn’t require these to appear in sys/types.h, so in
principle they ought to be brought under __USE_MISC also.  But, when I
tried that it broke about two dozen files just in our own source tree,
and POSIX doesn’t *forbid* sys/types.h to define these types, so I
think we should leave them alone.

	* posix/sys/types.h (u_int8_t, u_int16_t, u_int32_t, u_int64_t)
        (register_t): Move under #ifdef __USE_MISC.
        Consolidate adjacent #ifdef __USE_MISC blocks.
        * scripts/check_obsolete_constructs.py: Add register_t to the
        set of obsolete typedefs that our headers should not use
        (but sys/types.h may still define).
---
 NEWS                                 |  8 ++++++++
 posix/sys/types.h                    | 16 ++++++++--------
 scripts/check-obsolete-constructs.py |  1 +
 3 files changed, 17 insertions(+), 8 deletions(-)
  

Comments

Florian Weimer May 9, 2019, 8:34 a.m. UTC | #1
* Zack Weinberg:

> +* The typedefs u_int8_t, u_int16_t, u_int32_t, u_int64_t, and register_t
> +  are no longer defined by <sys/types.h> in strict conformance modes.
> +  These types were historically provided by <sys/types.h> on BSD systems,
> +  but are not part of the POSIX specification for that header.  Applications
> +  requiring fixed-width unsigned integer types should use the similarly
> +  named uint8_t, uint16_t, etc. from <stdint.h>.  There is no standardized
> +  replacement for register_t.

The challenge with register_t is that it's long long on x32 and MIPS64
with -mabi=n32.

And ideally, it would be the return type of the syscall function (which
is long int by incorrect tradition).

> diff --git a/posix/sys/types.h b/posix/sys/types.h
> index 1bbd896ad4..7327904346 100644
> --- a/posix/sys/types.h
> +++ b/posix/sys/types.h
> @@ -143,18 +143,20 @@ typedef __suseconds_t suseconds_t;
>  #define	__need_size_t
>  #include <stddef.h>
>  
> +/* POSIX does not require intN_t to be defined in this header, so
> +   technically this ought to be under __USE_MISC, but it doesn't
> +   forbid them to be defined here either, and much existing code
> +   expects them to be defined here.  */
> +#include <bits/stdint-intn.h>
> +
>  #ifdef __USE_MISC
>  /* Old compatibility names for C types.  */
>  typedef unsigned long int ulong;
>  typedef unsigned short int ushort;
>  typedef unsigned int uint;
> -#endif
>  
> -/* These size-specific names are used by some of the inet code.  */
> -
> -#include <bits/stdint-intn.h>
> -
> -/* These were defined by ISO C without the first `_'.  */
> +/* These size-specific names are used by some of the inet code.
> +   They were defined by ISO C without the first `_'.  */
>  typedef __uint8_t u_int8_t;
>  typedef __uint16_t u_int16_t;
>  typedef __uint32_t u_int32_t;

I think the comment refers to the same types as the comment above the
inclusion of <bits/stdint-intn.h>.  Maybe that could be made more clear
to the casual reader?

Rest of the patch looks fine to me.

Thanks,
Florian
  
Zack Weinberg May 22, 2019, 2:34 p.m. UTC | #2
On Thu, May 9, 2019 at 4:34 AM Florian Weimer <fweimer@redhat.com> wrote:
> > +* The typedefs u_int8_t, u_int16_t, u_int32_t, u_int64_t, and register_t
> > +  are no longer defined by <sys/types.h> in strict conformance modes.
> > +  These types were historically provided by <sys/types.h> on BSD systems,
> > +  but are not part of the POSIX specification for that header.  Applications
> > +  requiring fixed-width unsigned integer types should use the similarly
> > +  named uint8_t, uint16_t, etc. from <stdint.h>.  There is no standardized
> > +  replacement for register_t.
>
> The challenge with register_t is that it's long long on x32 and MIPS64
> with -mabi=n32.

Yes, patch 2 of this series had to introduce a MIPS-specific
bits/typesizes.h because of this.

> And ideally, it would be the return type of the syscall function (which
> is long int by incorrect tradition).

I don't want to change that in this patch series.

[sys/types.h]
> > +/* POSIX does not require intN_t to be defined in this header, so
> > +   technically this ought to be under __USE_MISC, but it doesn't
> > +   forbid them to be defined here either, and much existing code
> > +   expects them to be defined here.  */
> > +#include <bits/stdint-intn.h>
...
> > -/* These were defined by ISO C without the first `_'.  */
> > +/* These size-specific names are used by some of the inet code.
> > +   They were defined by ISO C without the first `_'.  */
> >  typedef __uint8_t u_int8_t;
> >  typedef __uint16_t u_int16_t;
> >  typedef __uint32_t u_int32_t;
>
> I think the comment refers to the same types as the comment above the
> inclusion of <bits/stdint-intn.h>.  Maybe that could be made more clear
> to the casual reader?

The important difference here is that intN_t are standard types (but
not standardized as provided by sys/types.h) so it's less troublesome
for us to provide them unconditionally, as existing code expects.
u_intN_t are not standard types so we really shouldn't provide them
unconditionally.  How's this for a comment?

/* These alternative names for uintN_t were used by pre-C99 networking code.
   Provided for backward compatibility only.  */

> Rest of the patch looks fine to me.

Thanks.  Nobody's looked at most of the rest of the patch series; do
you think you might have time to do it in the near future?

zw
  

Patch

diff --git a/NEWS b/NEWS
index 0d9236c38d..a4d34213b4 100644
--- a/NEWS
+++ b/NEWS
@@ -26,6 +26,14 @@  Deprecated and removed features, and other changes affecting compatibility:
   definitions in libc will be used automatically, which have been available
   since glibc 2.17.
 
+* The typedefs u_int8_t, u_int16_t, u_int32_t, u_int64_t, and register_t
+  are no longer defined by <sys/types.h> in strict conformance modes.
+  These types were historically provided by <sys/types.h> on BSD systems,
+  but are not part of the POSIX specification for that header.  Applications
+  requiring fixed-width unsigned integer types should use the similarly
+  named uint8_t, uint16_t, etc. from <stdint.h>.  There is no standardized
+  replacement for register_t.
+
 Changes to build and runtime requirements:
 
 * GCC 6.2 or later is required to build the GNU C Library.
diff --git a/posix/sys/types.h b/posix/sys/types.h
index 1bbd896ad4..7327904346 100644
--- a/posix/sys/types.h
+++ b/posix/sys/types.h
@@ -143,18 +143,20 @@  typedef __suseconds_t suseconds_t;
 #define	__need_size_t
 #include <stddef.h>
 
+/* POSIX does not require intN_t to be defined in this header, so
+   technically this ought to be under __USE_MISC, but it doesn't
+   forbid them to be defined here either, and much existing code
+   expects them to be defined here.  */
+#include <bits/stdint-intn.h>
+
 #ifdef __USE_MISC
 /* Old compatibility names for C types.  */
 typedef unsigned long int ulong;
 typedef unsigned short int ushort;
 typedef unsigned int uint;
-#endif
 
-/* These size-specific names are used by some of the inet code.  */
-
-#include <bits/stdint-intn.h>
-
-/* These were defined by ISO C without the first `_'.  */
+/* These size-specific names are used by some of the inet code.
+   They were defined by ISO C without the first `_'.  */
 typedef __uint8_t u_int8_t;
 typedef __uint16_t u_int16_t;
 typedef __uint32_t u_int32_t;
@@ -167,8 +169,6 @@  typedef __register_t register_t;
    defined.  */
 #define __BIT_TYPES_DEFINED__	1
 
-
-#ifdef	__USE_MISC
 /* In BSD <sys/types.h> is expected to define BYTE_ORDER.  */
 # include <endian.h>
 
diff --git a/scripts/check-obsolete-constructs.py b/scripts/check-obsolete-constructs.py
index 46535afcac..4317aa320d 100755
--- a/scripts/check-obsolete-constructs.py
+++ b/scripts/check-obsolete-constructs.py
@@ -254,6 +254,7 @@  class NoCheck(ConstructChecker):
 OBSOLETE_TYPE_RE_ = re.compile(r"""\A
   (__)?
   (   quad_t
+    | register_t
     | u(?: short | int | long
          | _(?: char | short | int(?:[0-9]+_t)? | long | quad_t )))
 \Z""", re.VERBOSE)