On Fri, Sep 07, 2018 at 08:01:07PM -0700, Linus Torvalds wrote: > On Fri, Sep 7, 2018 at 6:06 PM Luc Van Oostenryck > <luc.vanoostenryck@xxxxxxxxx> wrote: > > > > but currently your example can only be handled if the base type is selected > > in two passes. Is it worth? > > Maybe it doesn't matter. > > My personal expectation was actually that the base type of the values > would *always* be the "enum" itself, and then you'd just select the > type for the enum based on the values. Yes, this is what we had more or less agreed upon a few months ago. > Then there wouldn't be any difference between bitwise and non-bitwise > enums for the individual values. If you have > > enum a { > one = 1, > two = 2, > }; > > then "one" and 'two" are always of type "enum a". The only difference > with a bitwise enum and one that isn't would be that a non-bitwise > enum just then evaluates to "int" (or whatever the size is, based on > the value range) much more easily. > > Your approach (and what we used to do) is to get rid of the "enum a" > earlier, so that "one" is always just of type 'int". Or did I > mis-understand? It's indeed what's happening, but: * it's not really my approach, it's just the current situation. * I only reposted these patches now because of a bug repport [1]. The warning there is completly bogus and is caused by the combination of the UB shift (fixed in patch 3/12) and the fact that the base type is 'bad_ctype' (fixed in the next patches). * I really like having enum values like 'one' here above being of enum type (let's call this 'strong enums') but this is not OK regarding standard C. In itself, I suppose we don't really care but when I tried it I saw that it created problems in the kernel code. I don't remember exactly all the problems but there were some where a function expected some 'enum a' as argument and then was called with some other 'enum b' value. This is fine for C's 'weak enums' where each enum values are of type 'int' (or for GCC & sparse, some other integer type) but not OK 'strong enums' here (unless, of course, type_difference() is modified). Some of them were clearly error and I've corrected a bunch of them, but some others seemed quite deliberate. There was also some problems with function pointers. > Our enum handling has always been kind of half-arsed. Bah, I think that this series is already a nice cleaning. I'll try, in the following weeks, to clearly describe the whole situation about enums and the different possible choices. For your example: typedef long long __bitwise bits; enum a { one = 0, two = (__force bits) 1, }; I've found a clean way to handle it without needing two passes. -- Luc [1] https://lore.kernel.org/lkml/a70172863fa7d3c138f788b18d36524bd45b0a73.1536326078.git.christophe.leroy@xxxxxx/