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-21 22:48 +0100 |
| Organization | A noiseless patient Spider |
| Message-ID | <87lhghk3ex.fsf@bsb.me.uk> (permalink) |
| References | (16 earlier) <b7d0b707-df27-42df-bb8a-27c6d1702178@googlegroups.com> <871ticjr51.fsf@bsb.me.uk> <970ad69d-3e28-4171-955e-56f9a2dc7bf8@googlegroups.com> <87bnheoq46.fsf@bsb.me.uk> <006226b4-21dd-45a6-a1e8-54ee88705e3d@googlegroups.com> |
jadill33@gmail.com writes:
> On Wednesday, May 20, 2015 at 6:12:36 PM UTC-4, Ben Bacarisse wrote:
>> jadill..@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.
>
> The main motivation to use uint32_t is that it maps exactly to the
> binary data that I'm reading. I've never considered choosing unsigned
> long to read 32 bits, 2's complement, no padding bits from a file.
> Maybe it's an education thing, since I started learning C in the
> late nineties. In fact, my first reaction to using a C90 compiler
> without stdint.h was to create my own loose stdint.h wrapper (for serial
> port I/O of a message protocol).
>
>> Maybe you worry about the wasted space on some systems?
>
> At least in my mind, it was not a motivating factor to use stdint.h types
> for binary I/O.
>
>> 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?
>
> If I have a file whose data maps to the format the stdint.h typedefs
> represent, I prefer to use those types to represent them in memory.
> I like to declare the structures in memory to follow the exact binary
> format in the file as much as I can.
Yes, but I don't see why that is important to you.
> Exactly what scenario are you imagining where uint_least32_t is available
> but not uint32_t?
Obviously I am imagining exactly a situation where unit32_t does not
exist (like a 36-bit machine for example).
> Have you encountered it in the wild?
No. I've used machines where uin32_t would not exist but that was
before C99 was even written.
<snip>
>> 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?
>
> Just mapping the binary representation of the data in a file to the
> closest fit type that I can declare. The name of the integer type
> uint32_t (imo) more accurately reflects the type of data than
> 'unsigned long'.
Yes, it does. I didn't know that was your motivation. I thought you
were making some claim that its use helped in some more concrete way
than what it reflects.
> To ask the same question in a related way, do you
> use 'int' instead of 'bool' for boolean types, or do you define a
> wrapper for 'bool' in the case that the type definition doesn't exist?
I do both in different contexts. I also use uint32_t at times.
>> > 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.
>
> Here's an excerpt out of the Wireshark developer's guide.
>
> \quote
> Don't use "long" to mean "signed 32-bit integer", and don't use
> "unsigned long" to mean "unsigned 32-bit integer"; "long"s are 64 bits
> long on many platforms. Use "gint32" for signed 32-bit integers and use
> "guint32" for unsigned 32-bit integers.
> \endquote
>
> The only reason I mention it is that it's an example of what represents
> the attitude of a somewhat sizable developer community whose focus is on
> translating the contents of network packets into human readable text.
They are correct to say that. I am not saying that one should use long
to mean signed 32-bit integer. If you think I disagree with this
advice, I think I must have failed to get my point across.
I think that re-writing your example to use unsigned long (and to remove
the hidden assumptions and undefined behaviour) produces a function that
is just as useful, a little simpler, and ever so slightly more portable.
The result (an unsigned long) does not meet your criteria about matching
or reflecting the data, but it can represent the values and that, to me,
is more important.
> Okay, you say you're not claiming unsigned long is better in general,
> but you've spent quite a bit of time claiming that uint32_t is a poor
> choice of a data type, even for binary I/O in cases where the binary
> data matches the exact representation. What qualifies as a valid use
> of uint32_t if binary I/O is not one of them? Bit-field definitions?
No, you are completely misrepresenting my case. Reading a known-width
number from a binary file where you know the representation matches that
of the C implementation is a fine use of these types. You did not seem
to be suggesting that. You gave an example that did not do that and did
not, as far as I could tell, benefit from the use of uint32_t.
--
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