1

This question is for NXP/ FreeScale CodeWarrior MCU 10.5. Why does the following code extract result in the warning illegal implicit conversion from 'unsigned char' to >'const @enum$1cb_c' on the last line?

typedef enum { BOOL__FALSE, BOOL__TRUE } Bool_t;

typedef struct a { Bool_t b : 1; } a_t;

void d (Bool_t e);

a_t c = { BOOL__FALSE };

d ( c.b );
too honest for this site
  • 12,050
  • 4
  • 30
  • 52
Torsten Knodt
  • 477
  • 1
  • 5
  • 20
  • 1
    Can't reproduce. [mcve], please.. – Eugene Sh. Jul 31 '18 at 18:56
  • 1
    This code compiles OK on any of the compilers I use. Does not matter if compiled as C or C++ – 0___________ Jul 31 '18 at 18:58
  • if codewarrior does not compile - it means that is not 100% C or C++ or the error is in the code you do not show – 0___________ Jul 31 '18 at 19:00
  • do not use this kind of bool definitions. Use standard bool header. It is extremely error prone. – 0___________ Jul 31 '18 at 19:02
  • @Bathsheba It's more like reserved. Making any thread with P__J__ undefined :) – Eugene Sh. Jul 31 '18 at 19:31
  • Beware of using signed types for 1-bit bitfields. In two's complement it'll be able to hold values 0 and -1. It's implementation defined whether Bool_t in the example is signed or not, but if it it's signed, the 1-bit bitfield can't be BOOL__TRUE. Similarly, assigning basically any even value (like 2) to the field will lead to BOOL__FALSE, which is probably not what you'd expect. You'll end up needing to manually clamp values to your boolean type using, say, !!val. Use stdbool and these problems will go away. – Jani Mar 19 '19 at 15:33

1 Answers1

-5

Your compiler is correct:

C standard, 6.7.2.2p4: "Each enumerated type shall be compatible with char, a signed integer type, or an unsigned integer type. The choice of type is implementation-defined,but shall be capable of representing the values of all the members of the enumeration."

Your implementation seems to use some internal type to represent the enum type, which is valid.

Also see

6.7.2.1p10: "A bit-field is interpreted as having a signed or unsigned integer type consisting of the specified number of bits."

Using an unsigned char for the bit field is valid.

In general is it bad practice to use homebrew typedefs if standard types are available. C has a mandatory boolean type _Bool (resp. bool with supporting constant-macros using stdbool.h) which has the expected semantics (different from enums). Using it would have avoided the problems and is also portable between implementations.

In general, bit-field structs are of little use in C. There is no defined layout, underlying or other guarantees which might be expected. Most times a fixed-width integer type and bit-ops is the better choice. Interestingly, _Bool bit-fields are the type with most guarantees. So using this standard type would have avoided the problem.

too honest for this site
  • 12,050
  • 4
  • 30
  • 52
  • 7
    `In general, bit-field structs are of little use in C` very interesting. Where did you get this from? – 0___________ Aug 06 '18 at 12:28
  • 1
    @P__J__ Over 30 years of practice in C, detailed knowledge about the C standard and compiler construction vor various languages, a plethora of C ABIs for multiple CPUs and well paid projects by customers who tend to come to me if someonme messed their code up - not only, but including missconceptions about bitmap `struct`s. I wouldn't call it "intertesting" anymore; it's just sad. But thanks for the revenge downvote! Playing kindergarten? – too honest for this site Aug 06 '18 at 12:31
  • 9
    @toohonestforthissite so please write the leeter to the microchip or other uC companies as often they make it the most used way of the hardware register access (maybe they do no have 30years of experience ad they did not know that `bit-field structs are of little use in C`) Bitfields are in very common use. If you do not use them that is only your personal choice. Your nitpicking is a kindergarten play – 0___________ Aug 06 '18 at 12:38
  • 3
    @P__J__: Interstingly, most MCU headers use normal `uintN_t` pointers and bitops. But I wouldn't use them as a strong referencee, as they are typically written by students the cheap way. I've met quite some of them - nice people most of them, but rarely experts in the C language (interstingly two or three of the fix-it projects were exactly for such BSPs). But, hey, of course you know better! Just that: maybe you read about the difference of "no use" and "little use". Now, you have the last word, I've better to do, like jumping into the pool. – too honest for this site Aug 06 '18 at 12:42
  • Sorry for not looking into it that long and many thanks for your explanation. I accept the answer, because it explains the error message, which is what the question was about. But I also asked myself why they introduced `Bool_t` instead of using `stdbool.h`. The answer is, that it is implemented using pre-processor `#define`, which is not type-safe. But ISO 26262-6:2011 (Road vehicles -- Functional safety -- Part 6: Product development at the software level) "highly recommends" "enforcement of strong typing". So they replaced it with an own `enum`. – Torsten Knodt Oct 22 '18 at 20:40
  • 2
    @TorstenKnodt After doing a MISRA/AUTOSAR automotive project, I can assertain you that such homebrew macros are plain legacies and clearly not related to strong typing. On a sidenote: C is by standard not strongly typed and you definitively cannt do that using ´enum´s. Opposite, this makes things even worse. Said that, many such coding styles are pre-C99 crap, and solely still maintained because of many legacies and devs who did not go forward the last 20+ years. Yes, that is a harsh judegement, but at least for Embedded - more particularily Automotive - this is unfortunately well justified. – too honest for this site Mar 06 '21 at 16:50