Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Minor initialization issue with unions #411

Closed
monniaux opened this issue Sep 20, 2021 · 3 comments
Closed

Minor initialization issue with unions #411

monniaux opened this issue Sep 20, 2021 · 3 comments

Comments

@monniaux
Copy link
Contributor

#include <stdint.h>
#include <stdio.h>

union {
  int8_t;
  uint32_t c;
} toto = { 730 };

int main() {
  printf("%d\n", toto.c);
  return 0;
}

According to C17 6.7.9.17 "When no designations are present, subobjects of the current object are initialized in order according to the type of the current object: [...] the first named member of a union."

Accordingly, gcc considers that the initializer initializes c to 730. In contrast, CompCert considers that it initializes the unnamed field to 730, which gets truncated to 218. So it seems CompCert's behavior is incorrect.

I don't think this is something likely to show up in real code, except perhaps if the unnamed field is meant as some form of padding.

@m-schmidt
Copy link
Member

Just for completeness: C99 and C11 also state "...first named member of a union".

@monniaux
Copy link
Contributor Author

Note: in C11 and C17, anonymous fields that have union or structure type are treated specially, they expose their subfields (transitively) as though they were fields of the outer object. This is not the case here, but you may want to look into this.

@xavierleroy
Copy link
Contributor

For the record, a full analysis of this issue:

  • A declaration such as union { int8_t; uint32_t c; } is not allowed by the C99 grammar. The C11 grammar allows it (so as to support anonymous structs and unions) but gives it a meaning only if the type (here int8_t) is a struct or a union.
  • GCC and Clang both accept this declaration, even in strict C99 mode, and just ignore the int8_t member. For GCC compatibility, the CompCert parser accepts the declaration, but the elaborator was not ignoring it like it should. This is fixed in 2892e2c .
  • The "first named member of a union" prescription addresses unnamed bit-fields, as in union { int : 16; uint32_t c; }, which is legal C99 and C11. This is taken care of in 6ede270.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants