Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   C Programming (http://www.velocityreviews.com/forums/f42-c-programming.html)
-   -   c99 uint32_t (etc.) corresponding portable printf format specifiers? (http://www.velocityreviews.com/forums/t742641-c99-uint32_t-etc-corresponding-portable-printf-format-specifiers.html)

David Mathog 01-26-2011 06:40 PM

c99 uint32_t (etc.) corresponding portable printf format specifiers?
 
c99 introduced (or at least standardized) uint32_t, uint64_t etc., and
that provides a way to write code
so that the size of the variables remains the same on platforms where
int, long, etc. can be different sizes. So far so good. However,
there do not seem to be any corresponding fprintf specifiers, just the
existing l, ll and u. and those do not have a fixed size. So in c99
how does one write this code fragment portably?


#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>

uint32_t var=1;
fprintf(stdout,"%lu \n",var);

That would work on a 32 bit platform, but %lu could be 8 bytes on a 64
bit platform, rather than the intended 4 bytes.

Thanks,

David Mathog

Ben Pfaff 01-26-2011 06:48 PM

Re: c99 uint32_t (etc.) corresponding portable printf format specifiers?
 
David Mathog <dmathog@gmail.com> writes:

> c99 introduced (or at least standardized) uint32_t, uint64_t etc., and
> that provides a way to write code
> so that the size of the variables remains the same on platforms where
> int, long, etc. can be different sizes. So far so good. However,
> there do not seem to be any corresponding fprintf specifiers, just the
> existing l, ll and u. and those do not have a fixed size. So in c99
> how does one write this code fragment portably?
>
>
> #include <stdlib.h>
> #include <stdio.h>
> #include <stdint.h>
>
> uint32_t var=1;
> fprintf(stdout,"%lu \n",var);


#include <inttypes.h>
fprintf(stdout, "%"PRIu32" \n", var);
--
char a[]="\n .CJacehknorstu";int putchar(int);int main(void){unsigned long b[]
={0x67dffdff,0x9aa9aa6a,0xa77ffda9,0x7da6aa6a,0xa6 7f6aaa,0xaa9aa9f6,0x11f6},*p
=b,i=24;for(;p+=!*p;*p/=4)switch(0[p]&3)case 0:{return 0;for(p--;i--;i--)case+
2:{i++;if(i)break;else default:continue;if(0)case 1:putchar(a[i&15]);break;}}}

David Mathog 01-26-2011 06:57 PM

Re: c99 uint32_t (etc.) corresponding portable printf format specifiers?
 
On Jan 26, 10:48*am, b...@cs.stanford.edu (Ben Pfaff) wrote:
> #include <inttypes.h>
> fprintf(stdout, "%"PRIu32" \n", var);


Thanks! Which man page, if any, includes this information? It isn't
in the fprintf page on my
Linux systems.

Thank you,

David Mathog

Ben Pfaff 01-26-2011 07:11 PM

Re: c99 uint32_t (etc.) corresponding portable printf format specifiers?
 
David Mathog <dmathog@gmail.com> writes:

> On Jan 26, 10:48*am, b...@cs.stanford.edu (Ben Pfaff) wrote:
>> #include <inttypes.h>
>> fprintf(stdout, "%"PRIu32" \n", var);

>
> Thanks! Which man page, if any, includes this information? It isn't
> in the fprintf page on my
> Linux systems.


I doubt it appears in a manpage. One place it is documented is
in POSIX:

http://pubs.opengroup.org/onlinepubs...nttypes.h.html
--
"I'm not here to convince idiots not to be stupid.
They won't listen anyway."
--Dann Corbit

Keith Thompson 01-26-2011 07:48 PM

Re: c99 uint32_t (etc.) corresponding portable printf format specifiers?
 
David Mathog <dmathog@gmail.com> writes:
> On Jan 26, 10:48*am, b...@cs.stanford.edu (Ben Pfaff) wrote:
>> #include <inttypes.h>
>> fprintf(stdout, "%"PRIu32" \n", var);

>
> Thanks! Which man page, if any, includes this information? It isn't
> in the fprintf page on my
> Linux systems.


I don't know which man page it's in, if any, but it's documented
(defined, actually) in section 7.8 of the C99 standard. The latest
almost-official draft is at
http://www.open-std.org/JTC1/SC22/WG...docs/n1256.pdf

This won't tell you whether your implementation supports it; not
all do, and you might not get a warning for an unsupported format.

For simplicity, you might also consider converting to intmax_t or
uintmax_t (var was declared as uint32_t):

fprintf(stdout, "%ju\n", (uintmax_t)var);

Use "%ju" and cast to uintmax_t for unsigned variables, use "%jd" and
cast to intmax_t for signed variables. Personally, I find that easier
to remember than PRIu32 and friends. Widening to uintmax_t or intmax_t
might be more expensive, but that's hardly likely to be significant.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Ben Pfaff 01-26-2011 08:21 PM

Re: c99 uint32_t (etc.) corresponding portable printf format specifiers?
 
Keith Thompson <kst-u@mib.org> writes:
> For simplicity, you might also consider converting to intmax_t or
> uintmax_t (var was declared as uint32_t):
>
> fprintf(stdout, "%ju\n", (uintmax_t)var);
>
> Use "%ju" and cast to uintmax_t for unsigned variables, use "%jd" and
> cast to intmax_t for signed variables. Personally, I find that easier
> to remember than PRIu32 and friends. Widening to uintmax_t or intmax_t
> might be more expensive, but that's hardly likely to be significant.


One possible consideration is that it is fairly easy to #define
PRIu32, etc. on C89 systems that don't natively have <inttype.h>,
but it is harder to extend a system's printf implementation to
support the new C99 width modifiers such as 'j'.
--
"Debugging is twice as hard as writing the code in the first place.
Therefore, if you write the code as cleverly as possible, you are,
by definition, not smart enough to debug it."
--Brian Kernighan

Edward Rutherford 01-26-2011 08:28 PM

Re: c99 uint32_t (etc.) corresponding portable printf formatspecifiers?
 
Ben Pfaff wrote:
> Keith Thompson <kst-u@mib.org> writes:
>> For simplicity, you might also consider converting to intmax_t or
>> uintmax_t (var was declared as uint32_t):
>>
>> fprintf(stdout, "%ju\n", (uintmax_t)var);
>>
>> Use "%ju" and cast to uintmax_t for unsigned variables, use "%jd" and
>> cast to intmax_t for signed variables. Personally, I find that easier
>> to remember than PRIu32 and friends. Widening to uintmax_t or intmax_t
>> might be more expensive, but that's hardly likely to be significant.

>
> One possible consideration is that it is fairly easy to #define PRIu32,
> etc. on C89 systems that don't natively have <inttype.h>, but it is
> harder to extend a system's printf implementation to support the new C99
> width modifiers such as 'j'.


Another consideration is that it's all very well saying that an
unnecessary type widening is "hardly likely to be significant", but this
sort of casual disregard for efficiency has a tendency to snowball, so
that in the end a whole lot of things that individually are "hardly
likely to be significant" accumulate into major bloat and slowdown.

David Mathog 01-26-2011 08:52 PM

Re: c99 uint32_t (etc.) corresponding portable printf format specifiers?
 
On Jan 26, 11:48*am, Keith Thompson <ks...@mib.org> wrote:
>
> For simplicity, you might also consider converting to intmax_t or
> uintmax_t (var was declared as uint32_t):
>
> * * fprintf(stdout, "%ju\n", (uintmax_t)var);
>
> Use "%ju" and cast to uintmax_t for unsigned variables, use "%jd" and
> cast to intmax_t for signed variables.


The variables correspond to fixed width fields in binary files. I'm
not entirely clear
on what uintmax_t is, but my first impression was that it was "the
biggest int that this
platform can handle". So on a 64 bit platform wouldn't that be a 64
bit int? Which is not
what is needed when the file has 32 bit fields. Well, I guess it
would work for the printf,
but there would be problems trying to stuff data back into the 32 bit
field from the 64 bit int.

Thanks,

David Mathog

Keith Thompson 01-26-2011 10:20 PM

Re: c99 uint32_t (etc.) corresponding portable printf format specifiers?
 
David Mathog <dmathog@gmail.com> writes:
> On Jan 26, 11:48*am, Keith Thompson <ks...@mib.org> wrote:
>>
>> For simplicity, you might also consider converting to intmax_t or
>> uintmax_t (var was declared as uint32_t):
>>
>> * * fprintf(stdout, "%ju\n", (uintmax_t)var);
>>
>> Use "%ju" and cast to uintmax_t for unsigned variables, use "%jd" and
>> cast to intmax_t for signed variables.

>
> The variables correspond to fixed width fields in binary files. I'm
> not entirely clear on what uintmax_t is, but my first impression was
> that it was "the biggest int that this platform can handle".


No, it's the biggest *unsigned integer type* supported by the C
implementation. Remember that "int" is just one of several predefined
integer types; it's not just a shorter way of saying "integer".

Specifically, quoting C99 7.18.1.5:

The following type designates a signed integer type capable of
representing any value of any signed integer type:

intmax_t

The following type designates an unsigned integer type capable
of representing any value of any unsigned integer type:

uintmax_t

These types are required.

> So on a
> 64 bit platform wouldn't that be a 64 bit int?


It would probably be a 64-bit *integer*, though it's possible that a C
implementation on a 64-bit platform might also support 128-bit integers.

> Which is not what is
> needed when the file has 32 bit fields. Well, I guess it would work
> for the printf, but there would be problems trying to stuff data back
> into the 32 bit field from the 64 bit int.


No, you don't *need* to use 64 bits. The point is simply that
converting printf arguments to int64_t or uint64_t means there's less
stuff to keep track of; you don't have to remember that the conversion
macros for uint32_t, uint_fast32_t, and uint least32_t are PRIu32,
PRIuLEAST32, and PRIuFAST32, respectively. And if you change the
definition of your variable from uint32_t to uint64_t, the printf will
still work correctly. Converting from 32 bits to 64 probably imposes
some runtime overhead, but it's probably swamped by the overhead
of printf() parsing the format string and printing the output.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"


All times are GMT. The time now is 10:20 PM.

Powered by vBulletin®. Copyright ©2000 - 2014, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.