Hi Martin, On 11/13/22 16:32, Martin Uecker wrote: > Am Sonntag, den 13.11.2022, 16:15 +0100 schrieb Alejandro Colomar: >> Hi Martin, >> >> On 11/13/22 15:58, Martin Uecker wrote: >>> Am Sonntag, den 13.11.2022, 15:02 +0100 schrieb Alejandro Colomar: >>>> On 11/13/22 14:33, Alejandro Colomar wrote: >>>>> On 11/13/22 14:19, Alejandro Colomar wrote: >>>>>>> But there are not only syntactical problems, because >>>>>>> also the type of the parameter might become relevant >>>>>>> and then you can get circular dependencies: >>>>>>> >>>>>>> void foo(char (*a)[sizeof *.b], char (*b)[sizeof *.a]); >>>>>> >>>>>> This seems to be a difficult stone in the road. >>> >>> But note that GNU forward declarations solve this nicely. >> >> How would that above be solved with GNU fwd decl? I'm guessing that it can't. >> How do you forward declare incomplete VMTs?. > > You can't express it. This was my point: it is impossible > to create circular dependencies. > > ... > >>>>>> { >>>>>> for (/* void */; dst <= end; dst++) { >>>>>> *dst = *src++; >>>>>> if (*dst == '\0') >>>>>> return dst; >>>>>> } >>>>>> /* Truncation detected */ >>>>>> *end = '\0'; >>>>>> >>>>>> #if !defined(NDEBUG) >>>>>> /* Consume the rest of the input string. */ >>>>>> while (*src++) {}; >>>>>> #endif >>>>>> >>>>>> return end + 1; >>>>>> } >>>>> And I forgot to say it: Default promotions rank high (probably the highest) in >>>>> my list of most hated features^Wbugs in C. >>> >>> If you replaced them with explicit conversion you then have >>> to add by hand all the time, I am pretty sure most people >>> would hate this more. (and it could also hide bugs) >> >> Yeah, casts are also in my top 3 list of things to avoid (although in this case >> there's no bug); maybe a bit over default promotions :) >> >> I didn't mean that all promotions are bad. Just the gratuitous ones, like >> promoting everything to int before even needing it. That makes uint16_t a >> theoretical type, because whenever you try to use it, you end up with a signed >> 32-bit type; fun heh? :P _BitInt() solves that for me. > > uint16_t is for storing data. My expectation is that people > will find _BitInt() difficult and error-prone to use for > small sizes. But maybe I am wrong... I'm a bit concerned about the suffix to create literals. I'd have preferred a suffix that allowed creating a specific size (instead of the minimum one. i.e., 1u16 or something like that. But otherwise I think it can be better. I don't have in mind a big issue I had a year ago with uint16_t, but it required 3 casts in a line. With _BitInt() I think none (or maybe one, for giving 1 the appropriate size) would have been needed. But we'll see how it works out. > >> But sure, in (1u + 1l), promotions are fine to get a common type. >> >>>>> I wouldn't convert it to size_t, but >>>>> rather follow normal promotion rules. >>> >>> The point of making it size_t is that you then >>> do need to know the type of the parameter to make >>> sense of the expression. If the type matters, then you get >>> mutual dependencies as in the example above. >> >> Except if you treat incomplete types as... incomplete types (for which sizeof() >> is disallowed by the standard). And the issue we're having is that the types >> are not yet complete at the time we're using them, aren't they? > > It is not an incomplete type. When doing parsing and do not have > a declaration we know nothing about it (not just not the size). > If we assume we know the type (by looking ahead) we get mutual > dependencies. Then I'd do the following: .identifier always has an incomplete type. I'm preparing a complete description of what I think of the feature. I'll add that. > > Also the capability to parse, fold, and do type checking > in one go is something worth preserving in my opinion. Makes sense. Thanks for all the help, both! Cheers, Alex --