Re: is fstat or printf error?



ssszer@xxxxxxxxx wrote:

printf("dev:%d, %d, %d\n", st.st_dev, 1, 5); // <======

dev:2049, 0, 1

/usr/include/bits/typesizes.h:

#define __DEV_T_TYPE __UQUAD_TYPE

yes, it's (unsigned long long) in my host.
printf cast it to int, and it should not affect
the others thing, should it?

The error occurs because printf(3) does _not_ cast
the (unsigned long long) to int. The typedef in the
included file <sys/stat.h> tells the compiler that
st.st_dev is a 64-bit wide integer, so consequently
a 64-bit value is pushed on the stack. The function
printf, however, examines the first parameter (the
format string) and discovers '%d', meaning that the
second parameter is supposed to be a 32-bits signed
integer (at least on linux systems, not for example,
on *BSD). Therefore, printf consumes only one 32-bits
value from the stack, then proceeds with the next
'%d' in the format string. Again one 32-bits value
from the stack is "matched" to '%d', but that's not
the '1' parameter, it's the remainder of the 64-bits
wide st.st_dev. The third '%d' in the format string
will then be performed with the '1' parameter, and
the last parameter ('5') will never be touched by
printf.

To make it work you'll either have to use a different
format specifier ('%llu' in stead of '%d') or insert
an explicit cast (i.e. (int)st.st_dev). Obviously,
the cast will discard the most significant 32 bits
from st.st_dev.

The portable solution is the combination of format
specifier '%ju' and an explicit cast:
(uintmax_t)st.st_dev
For the 'max' integer types:
#include <stdint.h>

If you use gcc to compile, then put the "-Wall" option
in your Makefile.

Is __UQUAD_TYPE , i.e. unsigned long long, special to
printf, isn't it?

__UQUAD_TYPE is an internal macro to glibc. On 32-bit
linux systems it will expand to "unsigned long long",
on 64-bit systems it expands to "unsigned long".
The glibc printf recognises '%llu' and '%qu' for an
"unsigned long long" parameter.


Regards,
Marcel
--
printf -v email $(echo \ 155 141 162 143 145 154 155 141 162 \
143 145 154 100 157 162 141 156 147 145 56 156 154 | tr \ \\)
# O Herr, lass Hirn vom Himmel fallen! #
.



Relevant Pages

  • Re: pointer
    ... I think you need %02hhx there, or cast pto (unsigned int). ... Technically, yes, but it's also worth pointing out that implementations ... corresponding unsigned type, and vice versa, so for printf not to accept ...
    (comp.lang.c)
  • Re: problem incrementing my variable
    ... int i = 42; ... both printf calls are incorrect. ... Unless the format string is computed at run time and imposed by ... I find casts on *printf parameters to ...
    (comp.lang.c)
  • Re: why the printf is not typecasting the int to float
    ... The printf() family uses the variadic function interface (see ... 'int') must match exactly the type specified in the format string ...
    (comp.lang.c)
  • Re: Dynamic Printf
    ... file with an unknown number of columns at compile time, ... call to printf for each column. ... format string then call the number to string converter and pump it out ... void outputLine6 (int mode, int a, int b, int c, int d, int e, int f) ...
    (comp.lang.c)
  • Re: [BC] C tutorial q4
    ... things to print as specified in that format string. ... first of which is an int. ... printf() does exactly as you've asked ... and prints that int and a newline and nothing more. ...
    (comp.lang.c)