--- Begin Message ---
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

Reply via email to