tcpdump mailing list archives
Re: [tcpdump] About HAVE_NO_PRINTF_Z
From: Guy Harris via tcpdump-workers <tcpdump-workers () lists tcpdump org>
Date: Thu, 12 Jan 2023 00:10:22 -0800
--- Begin Message --- From: Guy Harris <gharris () sonic net>
Date: Thu, 12 Jan 2023 00:10:22 -0800
On Jan 11, 2023, at 11:06 PM, Guy Harris via tcpdump-workers <tcpdump-workers () lists tcpdump org> wrote:On UN*Xes, the C library is typically the system API library, so it's bundled with the OS rather than the compiler, so I don't know whether this is an issue of Sun C 5.9 or SunOS 5.9 (the core OS part of Solaris 9).Solaris 9 printf() man page: https://docs.oracle.com/cd/E19683-01/816-0213/6m6ne387j/index.html "An optional h specifies that a following d, i, o, u, x, or X conversion character applies to a type short int or type unsigned short int argument (the argument will be promoted according to the integral promotions, and its value converted to type short int or unsigned short int before printing); an optional h specifying that a following n conversion character applies to a pointer to a type short int argument; an optional l (ell) specifying that a following d, i, o, u, x, or X conversion character applies to a type long int or unsigned long int argument; an optional l (ell) specifying that a following n conversion character applies to a pointer to a type long int argument; an optional ll (ell ell) specifying that a following d, i, o, u, x, or X conversion character applies to a type long long or unsigned long long argument; an optional ll (ell ell) specifying that a following n conversion character applies to a pointer to a long long argument; or an optional L specifying that a following e, E, f, g, or G conversion character applies to a type long double argument. If an h, l, ll, or L appears with any other conversion character, the behavior is undefined." No mention of z. Solaris 10 printf() man page: https://docs.oracle.com/cd/E19253-01/816-5168/6mbb3hrj1/index.html "Length Modifiers The length modifiers and their meanings are: ... z Specifies that a following d, i, o, u, x, or X conversion specifier applies to a size_t or the corresponding signed integer type argument; or that a following n conversion specifier applies to a pointer to a signed integer type corresponding to size_t argument." So I suspect it's more like "C on Solaris 9 only supports %z if the compiler includes a library with a printf family that supports it and the compiler driver causes programs to be linked with that library before -lc; C on Solaris 10 and later supports %z even if the compiler relies on the system library for printf-family functions". I don't know whether any C99-supporting versions of GCC, when built on Solaris 9 for Solaris 9, provides their own printf-family functions with %z support. The GCC 4.6.4 manual says, in section 2 "Language Standards Supported by GCC": https://gcc.gnu.org/onlinedocs/gcc-4.6.4/gcc/Standards.html#Standards in subsection 2.1 "C language": The ISO C standard defines (in clause 4) two classes of conforming implementation. A conforming hosted implementation supports the whole standard including all the library facilities; a conforming freestanding implementation is only required to provide certain library facilities: those in <float.h>, <limits.h>, <stdarg.h>, and <stddef.h>; since AMD1, also those in<iso646.h>; and in C99, also those in <stdbool.h> and <stdint.h>. In addition, complex types, added in C99, are not required for freestanding implementations. The standard also defines two environments for programs, a freestanding environment, required of all implementations and which may not have library facilities beyond those required of freestanding implementations, where the handling of program startup and termination are implementation-defined, and a hosted environment, which is not required, in which all the library facilities are provided and startup is through a function int main (void) or int main (int, char *[]). An OS kernel would be a freestanding environment; a program using the facilities of an operating system would normally be in a hosted implementation. GCC aims towards being usable as a conforming freestanding implementation, or as the compiler for a conforming hosted implementation. By default, it will act as the compiler for a hosted implementation, defining __STDC_HOSTED__ as 1 and presuming that when the names of ISO C functions are used, they have the semantics defined in the standard. To make it act as a conforming freestanding implementation for a freestanding environment, use the option -ffreestanding; it will then define __STDC_HOSTED__ to 0 and not make assumptions about the meanings of function names from the standard library, with exceptions noted below. To build an OS kernel, you may well still need to make your own arrangements for linking and startup. See Options Controlling C Dialect. GCC does not provide the library facilities required only of hosted implementations, nor yet all the facilities required by C99 of freestanding implementations; to use the facilities of a hosted environment, you will need to find them elsewhere (for example, in the GNU C library). See Standard Libraries. So a conforming freestanding implementation does *not* have to support any of the printf-family routines (something else can provide them, e.g. at least some UN*X kernels provide their own version of sprintf()), and GCC does not provide printf-family routines, as they're required only of hosted implementations. "Standard Libraries" links to section 11.6 "Standard Libraries": https://gcc.gnu.org/onlinedocs/gcc-4.6.4/gcc/Standard-Libraries.html#Standard-Libraries which says: GCC by itself attempts to be a conforming freestanding implementation. See Language Standards Supported by GCC, for details of what this means. Beyond the library facilities required of such an implementation, the rest of the C library is supplied by the vendor of the operating system. If that C library doesn't conform to the C standards, then your programs might get warnings (especially when using -Wall) that you don't expect. For example, the sprintf function on SunOS 4.1.3 returns char * while the C standard says that sprintf returns an int. The fixincludes program could make the prototype for this function match the Standard, but that would be wrong, since the function will still return char *. If you need a Standard compliant library, then you need to find one, as GCC does not provide one. The GNU C library (called glibc) provides ISO C, POSIX, BSD, SystemV and X/Open compatibility for GNU/Linux and HURD-based GNU systems; no recent version of it supports other systems, though some very old versions did. Version 2.2 of the GNU C library includes nearly complete C99 support. You could also ask your operating system vendor if newer libraries are available. So merely having GCC 4.6.4 as your compiler doesn't affect whether %z is supported; %z will not work on Solaris 9 and will work on Solaris 10. So, if we care about %z support: on UN*Xes, we'd have to drop support for OSes that don't provide a C library that supports it; on Windows with MSVC, we'd have to require a version of MSVC whose library supports it (which I think we do); on Windows with other compilers, it depends on whether they provide their own library providing printf-family functions, in which case we'd have to require a compiler version with a library that supports %z, or they use the MSVC library, in which case we'd have to require that a version of the library be the one used. (The C library was not part of Windows until the Universal C Runtime. Prior to that, a lot of programs were either statically linked with the C runtime or had an installer that ran Microsoft's installer for the appropriate Visual C runtime. The Universal C Runtime: https://devblogs.microsoft.com/cppblog/introducing-the-universal-crt/ is distributed with Windows; it includes "all of the purely library parts of the CRT", with the remainder, the VCRuntime, which is, I think, still distributed with Visual Studio and which is not, I think, guaranteed to be compiler-independent, "[contains] the compiler support functionality required for things like process startup and exception handling". I suspect the idea is that you link statically with the VCRuntime, just as you link with crt0.o or whatever the equivalent is called with your compiler/OS on UN*X, and can link dynamically with the Universal C Runtime.)
--- End Message ---
_______________________________________________ tcpdump-workers mailing list tcpdump-workers () lists tcpdump org https://lists.sandelman.ca/mailman/listinfo/tcpdump-workers
Current thread:
- [tcpdump] About HAVE_NO_PRINTF_Z Francois-Xavier Le Bail via tcpdump-workers (Jan 11)
- Re: [tcpdump] About HAVE_NO_PRINTF_Z Guy Harris via tcpdump-workers (Jan 11)
- Re: [tcpdump] About HAVE_NO_PRINTF_Z Guy Harris via tcpdump-workers (Jan 12)
- Re: [tcpdump] About HAVE_NO_PRINTF_Z Denis Ovsienko via tcpdump-workers (Jan 12)
- Message not available
- Re: [tcpdump] About HAVE_NO_PRINTF_Z Denis Ovsienko via tcpdump-workers (Jan 14)
- Re: [tcpdump] About HAVE_NO_PRINTF_Z Denis Ovsienko via tcpdump-workers (Jan 30)
- Re: [tcpdump] About HAVE_NO_PRINTF_Z Denis Ovsienko (Feb 16)
- Re: [tcpdump] About HAVE_NO_PRINTF_Z Guy Harris via tcpdump-workers (Jan 12)
- Re: [tcpdump] About HAVE_NO_PRINTF_Z Guy Harris via tcpdump-workers (Jan 11)
- Message not available
- Re: [tcpdump] About HAVE_NO_PRINTF_Z Francois-Xavier Le Bail via tcpdump-workers (Jan 12)