Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
| Path | csiph.com!eternal-september.org!reader02.eternal-september.org!.POSTED!not-for-mail |
|---|---|
| From | Keith Thompson <Keith.S.Thompson+u@gmail.com> |
| Newsgroups | comp.std.c |
| Subject | Re: bit-fields of type unsigned long and unsigned long long |
| Date | Fri, 25 Jun 2021 02:02:35 -0700 |
| Organization | None to speak of |
| Lines | 160 |
| Message-ID | <87a6neuxjo.fsf@nosuchdomain.example.com> (permalink) |
| References | <sastag$a33$1@solani.org> <86fsx8bh88.fsf@linuxsc.com> <sb1hni$5t2$1@dont-email.me> <878s2zw30y.fsf@nosuchdomain.example.com> <sb2see$t4s$1@dont-email.me> <87v962vrh3.fsf@nosuchdomain.example.com> <sb44vv$frb$1@dont-email.me> |
| Mime-Version | 1.0 |
| Content-Type | text/plain |
| Injection-Info | reader02.eternal-september.org; posting-host="e76a60976a03f7b22ccc859f0f74fb19"; logging-data="6434"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX18acQOCLi9orzTkomIvmzgk" |
| User-Agent | Gnus/5.13 (Gnus v5.13) Emacs/27.2 (gnu/linux) |
| Cancel-Lock | sha1:aKomjdb4JMP5WDNt+WJybzTwWtM= sha1:r/1SbSXSqYJXvTVyFc+ZNa0GeXU= |
| Xref | csiph.com comp.std.c:6250 |
Show key headers only | View raw
David Brown <david.brown@hesbynett.no> writes:
> On 25/06/2021 00:16, Keith Thompson wrote:
>> David Brown <david.brown@hesbynett.no> writes:
>>> On 24/06/2021 20:06, Keith Thompson wrote:
>>>> David Brown <david.brown@hesbynett.no> writes:
>> [...]
>>>>> This would give a very different result from the way compilers implement
>>>>> bitfields today. In particular, consider :
>>>>>
>>>>> sizeof(struct { int8_t a : 1; });
>>>>>
>>>>> today, that is 1 on compilers that accept any integer type in bit
>>>>> fields. With your proposal, it would be sizeof(int).
>>>>
>>>> How does that follow? The bit field occupies only 1 bit. Why should
>>>> its underlying type affect the size of the structure?
>>>
>>> The current practice is that the size (and alignment) of the struct or
>>> its parts comes from the type used to declare the bit-field - just as
>>> for any other field. As I said below, it would be conceivable for a
>>> compiler to use the programmer's specified type to set the size of the
>>> containing struct or addressable storage unit, while ignoring it for the
>>> type of the field and how it is interpreted when used in an expression.
>>> That would, however, seem arbitrary and counter-intuitive, as well as
>>> being contrary to current practice and (if my interpretation is correct
>>> - but I might be wrong here) to C++ standards.
>>
>> (For simplicity, assume CHAR_BIT==8 and sizeof(int)==4.)
>>
>> I understand that it's existing practice, but it just doesn't make any
>> sense to me. If I define a struct with a bit-field defined as "unsigned
>> int:1", it's a single bit, not a 32-bit unsigned int object. I can pack
>> 8 of them into a single byte. I just don't see why the declared type
>> of a bit field should affect the size of the containing structure when
>> it has no effect on the size of the bit field itself. The structure
>> doesn't *need* those 32 bits of storage. If I add a second unsigned:1
>> bit-field, the structure doesn't grow by another 32 bits.
>>
>> As N1570 6.7.2.1p10 says, "A bit-field is interpreted as having a signed
>> or unsigned integer type consisting of the specified number of bits.",
>> so the bit-field object isn't really of type unsigned int.
>>
>> For an implementation that doesn't support types other than the
>> required ones, any struct with a 2-bit bit-field would have to be
>> at least 32 bits, while a struct with an unsigned char member could
>> be as small as 8 bits. (Same for a 1-bit bit-field pre-C99.) That
>> seems to me like an arbitrary restriction.
>>
>> I don't use bit-fields much, so maybe I'm missing some reason why this
>> behavior is reasonable and/or useful.
>>
>> [...]
>>
>
> As I see it, bit-fields are used for two main purposes.
>
> One is for structures internal to a program, in order to reduce space.
> There are two typical reasons for that. You might have a small embedded
> system with extremely small ram size (though these are getting less
> common, and since they are very rarely used with anything newer than
> C99, changes to the standard matter little there). Or you might have a
> bigger system with very large quantities of data, so that packing the
> data is important for efficiency. Common for these is that you don't
> really care about things like ordering, but you /do/ care that the sizes
> are what you expect. In particular, for efficiency on big systems too
> small is not better than too big - an array of 60 byte structs (with 4
> byte alignment) is going to be a lot slower than an array of 64 byte
> structs for many purposes.
>
> The other main use for bitfields is for matching external structures.
> These can be part of file formats, network packet formats, calls to
> functions from other languages, or hardware and peripherals. For this
> kind of use, precise specifications of all sizes, alignments, bit
> ordering, etc., is essential. The alternative is to use masks and
> shifting which is ugly and error-prone, but more portable.
>
> The bit-field requirements in the C specifications today are too limited
> and under-specified to be of much use for anything - they are not enough
> to do a good job of any common use-cases. (They could be useful for
> making compact structures for large arrays in the days before caches,
> when precise sizes mattered less.)
>
> The practical reality of bit-fields is that people use them based on the
> specifications given by their compiler and/or target ABI, using
> extensions provided by almost all good compilers (allowing any integer
> type or enumeration type), or using undocumented assumptions about
> sizes, alignments, ordering, etc., for their compiler and target.
>
> A change to the C standards which does not take them nearer to
> guaranteeing the practical use of today's tools and needs of today's
> programmers, is useless.
>
> A change to the C standards that goes against today's practice is worse
> than useless.
>
> A change that differs from the C++ standards (except in regarding the
> silly support for over-sized bit-fields) is worse than useless.
>
> A change that involves long, complicated reasoning about sizes and types
> but provides enough implementation-defined wiggle room to fit with
> today's implementations, is useless. The last thing the C standards
> need is more language that is confusing, open to interpretation, vague,
> and unhelpful to either compiler implementers or C programmers.
>
> If the C standard can't be changed to explicitly allow /all/ integer
> types in bit-fields, then making any change at all here is a waste of
> time and effort.
>
> If it can't be changed to mandate that the size of the allocation units
> matches the size of the type specified by the programmer as the
> bit-field type, then it must be left as it is (implementation-defined).
>
> If it can't be changed to mandate that the type of the bit-field matches
> the type specified by the programmer, then it must be left as it is.
I don't see an answer to my question anywhere in there.
To be perhaps a bit clearer, when I compile this program with gcc or
clang:
#include <stdio.h>
#include <limits.h>
int main(void) {
struct has_bit_field {
unsigned bit_field : 1;
};
struct has_unsigned_char {
unsigned char uc;
};
printf("CHAR_BIT = %d\n", CHAR_BIT);
printf("sizeof (unsigned) = %zu\n", sizeof (unsigned));
printf("sizeof (struct has_bit_field) = %zu\n", sizeof (struct has_bit_field));
printf("sizeof (struct has_unsigned_char) = %zu\n", sizeof (struct has_unsigned_char));
}
the output on my system is:
CHAR_BIT = 8
sizeof (unsigned) = 4
sizeof (struct has_bit_field) = 4
sizeof (struct has_unsigned_char) = 1
What is the rationale for a bit-field forcing the structure to be
expanded to 4 bytes, when the bit-field itself is only 1 bit?
Why does a 1-bit bit-field for a bigger structure size than an 8-bit
unsigned char member?
I understand that it's implementation-defined, probably ABI-defined, and
that changing it would break existing code that depends on this
behavior. I'm trying to understand why it was defined this way in the
first place. I see nothing in the C standard that suggests this (though
of course it does allow it).
I would have assumed that both struct has_bit_field and struct
has_unsigned_char could sensibly have a size of 1 byte.
--
Keith Thompson (The_Other_Keith) Keith.S.Thompson+u@gmail.com
Working, but not speaking, for Philips Healthcare
void Void(void) { Void(); } /* The recursive call of the void */
Back to comp.std.c | Previous | Next — Previous in thread | Next in thread | Find similar | Unroll thread
bit-fields of type unsigned long and unsigned long long Philipp Klaus Krause <pkk@spth.de> - 2021-06-22 16:49 +0200
Re: bit-fields of type unsigned long and unsigned long long David Brown <david.brown@hesbynett.no> - 2021-06-22 17:18 +0200
Re: bit-fields of type unsigned long and unsigned long long Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-06-22 11:17 -0700
Re: bit-fields of type unsigned long and unsigned long long Philipp Klaus Krause <pkk@spth.de> - 2021-06-23 08:25 +0200
Re: bit-fields of type unsigned long and unsigned long long David Brown <david.brown@hesbynett.no> - 2021-06-23 08:59 +0200
Re: bit-fields of type unsigned long and unsigned long long Philipp Klaus Krause <pkk@spth.de> - 2021-06-23 13:12 +0200
Re: bit-fields of type unsigned long and unsigned long long David Brown <david.brown@hesbynett.no> - 2021-06-23 14:14 +0200
Re: bit-fields of type unsigned long and unsigned long long Philipp Klaus Krause <pkk@spth.de> - 2021-06-23 17:45 +0200
Re: bit-fields of type unsigned long and unsigned long long Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-06-23 10:22 -0700
Re: bit-fields of type unsigned long and unsigned long long Philipp Klaus Krause <pkk@spth.de> - 2021-06-23 19:52 +0200
Re: bit-fields of type unsigned long and unsigned long long Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-06-23 16:12 -0700
Re: bit-fields of type unsigned long and unsigned long long David Brown <david.brown@hesbynett.no> - 2021-06-24 10:41 +0200
Re: bit-fields of type unsigned long and unsigned long long David Brown <david.brown@hesbynett.no> - 2021-06-24 10:32 +0200
Re: bit-fields of type unsigned long and unsigned long long Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-06-23 00:39 -0700
Re: bit-fields of type unsigned long and unsigned long long Philipp Klaus Krause <pkk@spth.de> - 2021-06-23 13:22 +0200
Re: bit-fields of type unsigned long and unsigned long long Philipp Klaus Krause <pkk@spth.de> - 2021-06-23 18:27 +0200
Re: bit-fields of type unsigned long and unsigned long long Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-06-23 10:53 -0700
Re: bit-fields of type unsigned long and unsigned long long Philipp Klaus Krause <pkk@spth.de> - 2021-06-23 20:13 +0200
Re: bit-fields of type unsigned long and unsigned long long Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-06-24 11:48 -0700
Re: bit-fields of type unsigned long and unsigned long long Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-06-24 12:23 -0700
Re: bit-fields of type unsigned long and unsigned long long David Brown <david.brown@hesbynett.no> - 2021-06-24 22:40 +0200
Re: bit-fields of type unsigned long and unsigned long long Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-07-10 09:13 -0700
Re: bit-fields of type unsigned long and unsigned long long Philipp Klaus Krause <pkk@spth.de> - 2021-06-24 22:14 +0200
Re: bit-fields of type unsigned long and unsigned long long Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-07-10 09:23 -0700
Re: bit-fields of type unsigned long and unsigned long long David Brown <david.brown@hesbynett.no> - 2021-06-24 11:02 +0200
Re: bit-fields of type unsigned long and unsigned long long Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-06-24 11:06 -0700
Re: bit-fields of type unsigned long and unsigned long long David Brown <david.brown@hesbynett.no> - 2021-06-24 23:11 +0200
Re: bit-fields of type unsigned long and unsigned long long Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-06-24 15:16 -0700
Re: bit-fields of type unsigned long and unsigned long long David Brown <david.brown@hesbynett.no> - 2021-06-25 10:43 +0200
Re: bit-fields of type unsigned long and unsigned long long Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-06-25 02:02 -0700
Re: bit-fields of type unsigned long and unsigned long long David Brown <david.brown@hesbynett.no> - 2021-06-25 13:54 +0200
Re: bit-fields of type unsigned long and unsigned long long Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-06-25 13:07 +0100
Re: bit-fields of type unsigned long and unsigned long long David Brown <david.brown@hesbynett.no> - 2021-06-25 15:17 +0200
Re: bit-fields of type unsigned long and unsigned long long Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-06-25 08:22 -0700
Re: bit-fields of type unsigned long and unsigned long long David Brown <david.brown@hesbynett.no> - 2021-06-25 18:22 +0200
Re: bit-fields of type unsigned long and unsigned long long Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-06-25 13:28 -0700
Re: bit-fields of type unsigned long and unsigned long long Ben Bacarisse <ben.usenet@bsb.me.uk> - 2021-06-25 19:12 +0100
Re: bit-fields of type unsigned long and unsigned long long Tim Rentsch <tr.17687@z991.linuxsc.com> - 2021-07-10 08:58 -0700
Re: bit-fields of type unsigned long and unsigned long long Keith Thompson <Keith.S.Thompson+u@gmail.com> - 2021-06-25 08:09 -0700
Re: bit-fields of type unsigned long and unsigned long long Philipp Klaus Krause <pkk@spth.de> - 2021-06-25 14:43 +0200
Re: bit-fields of type unsigned long and unsigned long long David Brown <david.brown@hesbynett.no> - 2021-06-25 15:33 +0200
Re: bit-fields of type unsigned long and unsigned long long Jakob Bohm <jb-usenet@wisemo.com.invalid> - 2021-07-06 23:18 +0200
csiph-web