Bug 23441 – importc: array length macro preprocessed with cpp doesn't compile

Status
RESOLVED
Resolution
INVALID
Severity
blocker
Priority
P1
Component
dmd
Product
D
Version
D2
Platform
x86_64
OS
All
Creation time
2022-10-28T00:29:02Z
Last change time
2023-01-19T03:25:05Z
Keywords
ImportC
Assigned to
No Owner
Creator
ryuukk_

Comments

Comment #0 by ryuukk.dev — 2022-10-28T00:29:02Z
The following code: ``` --- test.d import bar; void main() { int len; foo(&len); } --- bar.c struct nk_utfmask { int test; }; void foo(int* i) { // #define NK_LEN(a) (sizeof(a)/sizeof(a)[0]) // for(*i = 0; *i < (int)NK_LEN(nk_utfmask); ++(*i)) // expended using `cpp -E` on linux // for(*i = 0; *i < (int)(sizeof(nk_utfmask)/sizeof(nk_utfmask)[0]); ++(*i)) { } } ``` Error: bar.c(10): Error: found `[` when expecting `)` bar.c(10): Error: found `0` when expecting `;` following `for` condition bar.c(10): Error: expression expected, not `]` bar.c(10): Error: found `)` when expecting `;` following statement Apparently it's not valid C11, but that's the preprocessor output, so i'm not sure what i should do, i lack understanding on the syntax itself unfortunately
Comment #1 by ryuukk.dev — 2022-10-28T00:33:04Z
If that's not valid C11, then what would be the proper fix? so i could notify the project owners about a possible PR to make it compatible with C11
Comment #2 by kinke — 2022-10-28T01:08:30Z
That's invalid C in general, neither gcc nor clang accept it. `nk_utfmask` needs to be an array, e.g., `char nk_utfmask[5];`, which should be closer to the presumable original code (https://github.com/vurtun/nuklear/blob/6b9f937475db9280d966f44f469bc80191b5092a/nuklear.h#L7865). That NK_LEN macro apparently makes use of a weird special syntax to get the length of a C array, see the last 'notes' paragraph in https://en.cppreference.com/w/c/language/sizeof.
Comment #3 by ryuukk.dev — 2022-10-28T02:56:57Z
Oops i copied the wrong code above, it's not a struct you are right Here is the source: https://github.com/Immediate-Mode-UI/Nuklear/blob/6e80e2a646f35be4afc157a932f2936392ec8f74/src/nuklear_utf8.c I now remember, i sent a PR a while ago to fix it: https://github.com/Immediate-Mode-UI/Nuklear/pull/467
Comment #4 by ryuukk.dev — 2022-10-28T03:02:31Z
> That NK_LEN macro apparently makes use of a weird special syntax to get the length of a C array, see the last 'notes' paragraph in https://en.cppreference.com/w/c/language/sizeof. So it is valid C11 code? or should this issue be closed?
Comment #5 by bugzilla — 2023-01-19T03:18:53Z
(In reply to kinke from comment #2) > That NK_LEN macro apparently makes use of a weird special syntax to get the > length of a C array, see the last 'notes' paragraph in > https://en.cppreference.com/w/c/language/sizeof. The cite says: "Number of elements in any array a including VLA (since C99) may be determined with the expression sizeof a / sizeof a[0]. Note that if a has pointer type (such as after array-to-pointer conversion of function parameter type adjustment), this expression would simply divide the number of bytes in a pointer type by the number of bytes in the pointed type."
Comment #6 by bugzilla — 2023-01-19T03:25:05Z
(In reply to ryuukk_ from comment #0) > // #define NK_LEN(a) (sizeof(a)/sizeof(a)[0]) The usual way this is written: #define NK_LEN(a) (sizeof(a)/sizeof((a)[0])) But in order to work, `a` must be a static array. nk_utfmask is a struct. It will also fail because in C, it would have to be `struct nk_utfmask`, not just `nk_utfmask`. I'm going to mark this as invalid.