clay
clay copied to clipboard
[Core] Fix more C99 compliance issues
This fixes almost all the C99 compliance issues in the implementation of Clay.
Now the only issues remaining are:
- [ ]
##__VA_ARGS__(and related), which isn't easy to solve without switching to C23. - [x] Defining a struct within
offsetofto get the alignment of a type, which also isn't easy to solve without switching to C11. (Solved using macro magic) - [ ] A number of times that signed integers are compared with unsigned integers, which will need some rethinking of all the types for lengths and indices etc.
- [ ] Some strangeness with the
CLAY_SIZING_FITandCLAY_SIZING_GROWmacros, which don't compile without specifying-std=gnu99rather than-std=c99for some reason. - [ ] (The compiler warning on GCC discussed below. Not actually standards-non-compliant, but it does complain.)
Would you mind also fixing MSVC C99 compliance issues in your PR ? ATM it forces the rust bindings to use a .cpp file for compilation of clay under windows. The main issue is https://github.com/nicbarker/clay/blob/main/clay.h#L124, a potential fix was provided by emoon:
#ifdef _MSC_VER
#define CLAY_PACKED_ENUM __pragma(pack(push, 1)) enum __pragma(pack(pop))
#else
#define CLAY_PACKED_ENUM enum __attribute__((__packed__))
#endif
I really can't figure out why the GCC test is failing :-(. I can reproduce it, but I can't figure out which of the changes in this PR are causing it.
From what i'm reading, it seems like CLAY__CONFIG_WRAPPER should have braces somewhere around an initializer
I've figured out what the issue is, but unfortunately it's not easy to fix... I'll have a think and come back on this soon.
Would you mind expanding on what the issue is ?
Also is it for a specific reason you keep some CLAY_INIT calls, and remove others ?
Would you mind expanding on what the issue is ? Also is it for a specific reason you keep some
CLAY_INITcalls, and remove others ?
It's to do with the fact that we're now initialising the structs with {0} rather than {}, as {} is only added in C23. However, it does mean that the 0 could be initialising a field in a subobject rather than directly in the struct. GCC wants us to add braces around the 0 in that case to make it clear to the programmer that it's initialising a subobject, but that is difficult to do if you want to do it generically for all structs.
My general idea with removing the CLAY__INIT calls is to reduce the number of casts as much as possible. When initialising a struct, it's unnecessary to cast the braces to the right type, as it's already given in the variable declaration. Adding these casts mostly just adds possibilities for type errors to occur, because casts often implicitly tell compilers to not warn about type errors. The only CLAY__INIT calls I've left in are those that are necessary, like when you're creating a struct in the arguments to a function.
Confirming for posterity that we're going to move forward assuming a compiler that has support for ##__VA_ARGS__ 🙂
A number of times that signed integers are compared with unsigned integers, which will need some rethinking of all the types for lengths and indices etc.
We will tackle this in a separate PR so we can get this over the line!