Path: csiph.com!eternal-september.org!feeder.eternal-september.org!reader01.eternal-september.org!.POSTED!not-for-mail From: Keith Thompson Newsgroups: comp.lang.c Subject: Re: Sort char array Date: Fri, 18 Oct 2019 12:05:53 -0700 Organization: None to speak of Lines: 92 Message-ID: References: <5alnF.1041354$WI2.353384@fx34.am4> <87tv8ggaxh.fsf@bsb.me.uk> <87mue8fx7b.fsf@bsb.me.uk> <1QInF.797536$aq7.506537@fx09.am4> <875zkwf27e.fsf@bsb.me.uk> <87a7a66eyk.fsf@bsb.me.uk> <05020370-4edc-457f-a038-f51efbb47cdf@googlegroups.com> <87tv8d4kys.fsf@bsb.me.uk> <3obpF.121293$LC2.25145@fx45.iad> <86tv874jsq.fsf@linuxsc.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Injection-Info: reader02.eternal-september.org; posting-host="ab1d3158356d5814a548c66077976bea"; logging-data="11600"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX1/9KoJj+0Xq+q3i6+tJpGXk" User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (gnu/linux) Cancel-Lock: sha1:9Xmgex4e93GLJ6d/BXz4EgdYtjw= sha1:1d3NN9FcAdMhHlZ8kid2meTf4LU= Xref: csiph.com comp.lang.c:147045 Richard Damon writes: > On 10/17/19 8:51 AM, Tim Rentsch wrote: >> Richard Damon writes: >> >>> C has 11 standard integer types. PERIOD. >> >> An argument could be made that C has 12 standard integer types, >> since 'signed int' is not perfectly identical to 'int'. (The >> difference arises in declaring bitfield members.) Besides that >> miniscule exception though you assertions are spot on. > > Except that for a bit field, the declaration of the type of a field as > int doesn't create a type that is distinct from signed int and unsigned > int like char does, but is implementation defined if int is to be > considered as signed int or unsigned int. In other words, no bit field > member has a type of 'int', but only signed int or unsigned int, and a > field declared as just int will be treated as one or the other as > defined and documented by the implementation. Yes. N1570 6.7.2p5: Each of the comma-separated multisets designates the same type, except that for bit-fields, it is implementation-defined whether the specifier int designates the same type as signed int or the same type as unsigned int. (The "multisets" include "int", "signed int", and "signed", for example. The term "multiset" is used rather than "set" because "long long" is distinct from "long".) > If I am reading the standard right, I think that decision only applies > to the literal string int (or after macro replacement), and not for a > typedef. That's not the intent, though I agree that it's implied by the normative wording. N1570 footnote 125 on 6.7.2.1p10 says: 125) As specified in 6.7.2 above, if the actual type specifier used is int or a typedef-name defined as int, then it is implementation-defined whether the bit-field is signed or unsigned. But by referring to "the specifier int" (a syntactic construct) rather than the type int, 6.7.2p5 fails to make that clear. (The name of a typedef defined as int is not "the specifier int".) But even in unambiguous cases, like struct { unsigned int bf:2; }; it's not clear what the type of bf is. 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. But what is that type? Since "unsigned int" is not a type consisting of 2 bits, I would argue that bf is not of type unsigned int. We can use _Generic to explore what type a compiler uses for a given bit-field. gcc gives bf the type "unsigned char:2" (a type that can't be named in a generic selection), while clang treats is as type "unsigned int" (which I'm not entirely sure is conforming). #include int main(void) { struct { unsigned int bf:2; } obj = { .bf = -1 }; _Generic( obj.bf, char: printf("obj.bf = %d (char)\n", obj.bf), unsigned char: printf("obj.bf = %d (unsigned char)\n", obj.bf), signed char: printf("obj.bf = %d (signed char)\n", obj.bf), int: printf("obj.bf = %d (int)\n", obj.bf), unsigned int: printf("obj.bf = %u (unsigned int)\n", obj.bf) ); } gcc gives an error: error: '_Generic' selector of type 'unsigned char:2' is not compatible with any association (And if the width is 8, it's of type unsigned char, not "unsigned char:8"). clang gives: obj.bf = 3 (unsigned int) -- Keith Thompson (The_Other_Keith) kst-u@mib.org Will write code for food. void Void(void) { Void(); } /* The recursive call of the void */