Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
| From | Ben Bacarisse <ben.usenet@bsb.me.uk> |
|---|---|
| Newsgroups | comp.lang.c |
| Subject | Re: determines if it is a signed type |
| Date | 2015-05-20 23:12 +0100 |
| Organization | A noiseless patient Spider |
| Message-ID | <87bnheoq46.fsf@bsb.me.uk> (permalink) |
| References | (16 earlier) <c82653e9-61b8-4591-9d81-dba647009d3b@googlegroups.com> <877fs4k0si.fsf@bsb.me.uk> <b7d0b707-df27-42df-bb8a-27c6d1702178@googlegroups.com> <871ticjr51.fsf@bsb.me.uk> <970ad69d-3e28-4171-955e-56f9a2dc7bf8@googlegroups.com> |
jadill33@gmail.com writes:
> On Tuesday, May 19, 2015 at 3:37:06 PM UTC-4, Ben Bacarisse wrote:
>> jadill..@gmail.com writes:
>>
>> I'm just going to restart this from your example because the intervening
>> stuff does not help as far as I can see.
>>
>> > On Tuesday, May 19, 2015 at 12:08:36 PM UTC-4, Ben Bacarisse wrote:
>> >> jadill..@gmail.com writes:
>> >>
>> >> > On Tuesday, May 19, 2015 at 10:04:08 AM UTC-4, Ben Bacarisse wrote:
>> >> >> jadill..@gmail.com writes:
>> <snip>
>> >> >> > Yeah, one of the strongest motivations to use stdint.h is
>> >> >> > reading/writing
>> >> >> > binary protocols in files/sockets. You'll be hard pressed to avoid
>> >> >> > problems on multiple platforms without using some mechanism for
>> >> >> > defining fixed width types, and stdint.h is well, the standard way
>> >> >> > of defining the names of those types.
>>
>> <snip>
>> > Sure, here is what I use for reading 32-bit unsigned integers in little
>> > endian format from a file.
>> >
>> > \code snippet
>> > bool file_read_uint32_le( void *p, FILE *stream )
>> > {
>> > uint8_t buf[sizeof (uint32_t)];
>> > size_t bytes_read;
>> >
>> > /* argument error handling */
>> >
>> > bytes_read = fread( buf, 1, sizeof (buf), stream );
>> >
>> > if ( bytes_read == sizeof (uint32_t) ) {
>> > *((uint32_t*)p) = buf[0] + (buf[1] << 8) + (buf[2] << 16) + (buf[3] << 24);
>> > }
>> > else
>> > {
>> > if ( bytes_read > 0 ) {
>> > fseek( stream, -(long int)bytes_read, SEEK_CUR );
>> > }
>> >
>> > return false;
>> > }
>> >
>> > return true;
>> > }
>> > \endcode
>> >
>> > All I'm saying is that if instead of uint32_t I use a basic type, as
>> > in unsigned int, unsigned long, I can't guarantee that the code will
>> > work on platforms I care about.
>>
>> The use of types from stdint.h buys you nothing other than to limit the
>> code to those platforms that have uint32_t. The use of these types
>> might even prevent readers from seeing the non-portable assumptions
>> you've made about the implementation's int type and the possible
>> undefined behaviour of the shifts. (The argument -- in the reader's
>> head -- being that since the author is using those special types the
>> code must be a written to be portable.)
>
> I choose types from stdint.h because they *do* have a well defined
> binary representation (two's complement, no padding bits, and a fixed
> width). Many of the files I work with have those constraints (fixed
> width integers, no padding, 2's complement). If my interface was written
> in terms of reading into an unsigned long, I don't know whether the
> unsigned long is 32-bit/64-bits, has a one's complement representation,
> or has some number of padding bits.
Right, but you've not said why that matters to you, and that seems to me
to be the only point of disagreement. Maybe you have a specific
use-case in mind where the representation of the result matters, but
that's not been made explicit yet. Maybe you worry about the wasted
space on some systems? Yes, stdint.h can help with that, though even
here uint32_t looks to be the wrong choice. In those cases I'd go for
uint_least32_t which is guaranteed to be available. What use are you
imagining for the resulting value that makes the size, padding and bit
representation important?
<snip>
>> I made a point to exclude those simple cases where you can assume the
>> representation. My point was about cases like the example above where
>> you can't just fread and fwrite an object. If you have to shuffle the
>> bits, you might as well shuffle them into the most universal type that
>> can hold the value (unsigned long in the case above).
>
> I think this is where I get lost. Can you make a concrete example so
> I can try to wrap my head around it.
I mean cases where you can assume that the machine/compiler format
matches that of the file or protocol. In cases like that, reading
directly into a know-width type (maybe even a struct made of of several
of them) is the right solution. I think the Windows world has lots of
these sorts of files (at least I think it used to -- I am out of date).
>> > Hopefully I made it a bit clearer?
>>
>> Yes, clearer, but I remain un-convinced! I keep seeing code with
>> uint32_t in it which would be more portable without it. Not that it
>> usually matters, since odd machines without uint32_t are rare, and the
>> authors of such code almost certainly don't care about those that do
>> still exist.
>
> Well, if you wouldn't mind, would you define a small function to read
> a structure using your frame of reference for portability?
I don't have such a frame of reference. The situation usually
determines the portability and use to be made of the data usually has
huge impact on the storage format.
> 0 1 2 3
> 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
> +---------------------------------------------------------------+
> 0 | Block Type = 0x0A0D0D0A |
> +---------------------------------------------------------------+
> 4 | Block Total Length |
> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> 8 | Byte-Order Magic |
> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
> 12 | Major Version | Minor Version |
> +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
>
> This is a partial record from a pcap section header block. The question
> is what types do you use to read each of these values.
That can't be answered without knowing what is needed from the code. To
take a one example, a program that copies these records may only need to
extract the length (as a value) whilst storing the whole header as an
array of bytes. Other programs might need the numerical value of the
version number components, or maybe these are defined as byte strings
anyway?
The only field I'm pretty certain of how I'd like to read is the length
field. The header appears to have a byte order indicator which is in
line with how I understand pcap to work -- the byte order can vary even
within a file.
I'm not trying to duck the question. To read the length I'd write
unsigned long
read_32bits(FILE *fp, bool msb_1st)
{
unsigned long v = 0;
for (int b = 0; b < 4; b++)
v += (unsigned long)fgetc(fp) << 24*msb_1st + b*(8 - 16*msb_1st);
return v;
}
for which I've made the byte order a parameter (since that's how pcap
works I think) and I've omitted any error checking.
This seems simple and portable and I can't see what you are doing with
this value that would break if unsigned long were to have 60 bits, or to
have padding bits or whatever else. Why make the assumptions you made
in your example? How do they help?
> All of these values are unsigned, with 3 thirty-two bit fields,
> followed by 2 16-bit fields. Everything is 2's complement, no padding
> bits. Why is choosing unsigned long better than uint32_t?
In the case of reading just the one value, it simply makes fewer
assumptions about the implementation. But I'm not claiming it's better
in general -- I am doubting that uint32_t is better in quite the number
of situations where it is used.
--
Ben.
Back to comp.lang.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
determines if it is a signed type asetofsymbols@gmail.com - 2015-05-17 10:07 -0700
Re: determines if it is a signed type Richard Heathfield <rjh@cpax.org.uk> - 2015-05-17 18:12 +0100
Re: determines if it is a signed type asetofsymbols@gmail.com - 2015-05-17 10:34 -0700
Re: determines if it is a signed type asetofsymbols@gmail.com - 2015-05-17 11:09 -0700
Re: determines if it is a signed type Kusalananda <kusalananda@example.com> - 2015-05-17 18:22 +0000
Re: determines if it is a signed type asetofsymbols@gmail.com - 2015-05-17 11:31 -0700
Re: determines if it is a signed type Kusalananda <kusalananda@example.com> - 2015-05-17 19:59 +0000
Re: determines if it is a signed type Keith Thompson <kst-u@mib.org> - 2015-05-17 13:12 -0700
Re: determines if it is a signed type Morris Dovey <mrdovey@iedu.com> - 2015-05-17 19:08 -0500
Re: determines if it is a signed type Morris Dovey <mrdovey@iedu.com> - 2015-05-17 19:46 -0500
Re: determines if it is a signed type Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-05-18 01:59 +0100
Re: determines if it is a signed type Morris Dovey <mrdovey@iedu.com> - 2015-05-17 20:10 -0500
Re: determines if it is a signed type Keith Thompson <kst-u@mib.org> - 2015-05-18 00:37 -0700
Re: determines if it is a signed type Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-05-18 21:15 +0100
Re: determines if it is a signed type Keith Thompson <kst-u@mib.org> - 2015-05-18 15:15 -0700
Re: determines if it is a signed type glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-05-18 21:51 +0000
Re: determines if it is a signed type James Kuyper <jameskuyper@verizon.net> - 2015-05-18 18:00 -0400
Re: determines if it is a signed type glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-05-18 14:37 +0000
Re: determines if it is a signed type jacobnavia <jacob@jacob.remcomp.fr> - 2015-05-18 17:09 +0200
Re: determines if it is a signed type glen herrmannsfeldt <gah@ugcs.caltech.edu> - 2015-05-18 18:14 +0000
Re: determines if it is a signed type Richard Heathfield <rjh@cpax.org.uk> - 2015-05-18 06:34 +0100
Re: determines if it is a signed type Keith Thompson <kst-u@mib.org> - 2015-05-18 00:43 -0700
Re: determines if it is a signed type Richard Heathfield <rjh@cpax.org.uk> - 2015-05-18 13:56 +0100
Re: determines if it is a signed type Keith Thompson <kst-u@mib.org> - 2015-05-18 08:00 -0700
Re: determines if it is a signed type Richard Heathfield <rjh@cpax.org.uk> - 2015-05-18 20:35 +0100
Re: determines if it is a signed type jacobnavia <jacob@jacob.remcomp.fr> - 2015-05-18 23:08 +0200
Re: determines if it is a signed type Richard Heathfield <rjh@cpax.org.uk> - 2015-05-18 22:32 +0100
Re: determines if it is a signed type jacobnavia <jacob@jacob.remcomp.fr> - 2015-05-19 00:44 +0200
Re: determines if it is a signed type Richard Heathfield <rjh@cpax.org.uk> - 2015-05-19 00:05 +0100
Re: determines if it is a signed type jacobnavia <jacob@jacob.remcomp.fr> - 2015-05-19 01:43 +0200
Re: determines if it is a signed type Richard Heathfield <rjh@cpax.org.uk> - 2015-05-19 01:08 +0100
Re: determines if it is a signed type "Bartc" <bartc@freeuk.com> - 2015-05-19 11:33 +0100
Re: determines if it is a signed type Keith Thompson <kst-u@mib.org> - 2015-05-19 08:15 -0700
Re: determines if it is a signed type "Bartc" <bartc@freeuk.com> - 2015-05-19 19:36 +0100
Re: determines if it is a signed type Keith Thompson <kst-u@mib.org> - 2015-05-19 11:55 -0700
Re: determines if it is a signed type jacobnavia <jacob@jacob.remcomp.fr> - 2015-05-19 11:39 +0200
Re: determines if it is a signed type "Bartc" <bartc@freeuk.com> - 2015-05-19 11:44 +0100
Re: determines if it is a signed type jacobnavia <jacob@jacob.remcomp.fr> - 2015-05-19 12:11 +0200
Re: determines if it is a signed type jadill33@gmail.com - 2015-05-19 05:45 -0700
Re: determines if it is a signed type Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-05-19 15:03 +0100
Re: determines if it is a signed type jadill33@gmail.com - 2015-05-19 08:46 -0700
Re: determines if it is a signed type Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-05-19 17:08 +0100
Re: determines if it is a signed type jadill33@gmail.com - 2015-05-19 09:52 -0700
Re: determines if it is a signed type Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-05-19 20:36 +0100
Re: determines if it is a signed type jadill33@gmail.com - 2015-05-20 07:40 -0700
Re: determines if it is a signed type Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-05-20 23:12 +0100
Re: determines if it is a signed type jadill33@gmail.com - 2015-05-21 13:52 -0700
Re: determines if it is a signed type Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-05-21 22:48 +0100
Re: determines if it is a signed type jadill33@gmail.com - 2015-05-22 05:50 -0700
Re: determines if it is a signed type Ben Bacarisse <ben.usenet@bsb.me.uk> - 2015-05-22 23:14 +0100
Re: determines if it is a signed type jadill33@gmail.com - 2015-05-26 14:31 -0700
Re: determines if it is a signed type Tim Rentsch <txr@alumni.caltech.edu> - 2015-05-22 23:32 -0700
Re: determines if it is a signed type David Brown <david.brown@hesbynett.no> - 2015-05-20 12:26 +0200
Re: determines if it is a signed type Richard Heathfield <rjh@cpax.org.uk> - 2015-05-19 15:28 +0100
Re: determines if it is a signed type raltbos@xs4all.nl (Richard Bos) - 2015-05-23 10:37 +0000
Re: determines if it is a signed type Keith Thompson <kst-u@mib.org> - 2015-05-18 15:21 -0700
Re: determines if it is a signed type Richard Heathfield <rjh@cpax.org.uk> - 2015-05-19 00:04 +0100
Re: determines if it is a signed type Keith Thompson <kst-u@mib.org> - 2015-05-19 08:03 -0700
Re: determines if it is a signed type David Brown <david.brown@hesbynett.no> - 2015-05-19 08:47 +0200
Re: determines if it is a signed type Keith Thompson <kst-u@mib.org> - 2015-05-19 08:07 -0700
Re: determines if it is a signed type James Kuyper <jameskuyper@verizon.net> - 2015-05-18 11:28 -0400
Re: determines if it is a signed type Keith Thompson <kst-u@mib.org> - 2015-05-18 00:40 -0700
csiph-web