The current definitions of the __bswap_* macros prevent their use in a static/global context. For use with constant values, they should be usable even in a global context.
Created attachment 7996 [details] Patch to add tests to tst-bswap and tst-endian This patch adds tests for this bug. When building, you can clearly see the failure: In file included from ../bits/byteswap.h:34:0, from ../string/byteswap.h:24, from ../include/byteswap.h:1, from tst-bswap.c:19: ../bits/byteswap-16.h:26:6: error: braced-group within expression allowed only inside a function ({ unsigned short int __bsx = (unsigned short int) (x); \ ^ tst-bswap.c:28:28: note: in expansion of macro ‘__bswap_16’ static __uint16_t swap16 = __bswap_16(0x1234); ^ tst-bswap.c:31:1: error: initializer element is not constant static __uint32_t swap32 = __bswap_32(0x12345678); ^ tst-bswap.c:34:1: error: initializer element is not constant static __uint64_t swap64 = __bswap_64(0x1234567890abcdefULL); ^
FYI, I found this bug because the current linux kernel fails to build on BE platforms because of the use of htole16() and htole32() in the setup of a static variable in Documentation/mic/mpssd/mpssd.c; the failure is: In file included from /usr/include/bits/byteswap.h:34:0, from /usr/include/endian.h:60, from /usr/include/bits/waitstatus.h:64, from /usr/include/stdlib.h:42, from /root/linux/Documentation/mic/mpssd/mpssd.c:23: /root/linux/Documentation/mic/mpssd/mpssd.c:93:10: error: braced-group within expression allowed only inside a function .num = htole16(MIC_VRING_ENTRIES), ^ /root/linux/Documentation/mic/mpssd/mpssd.c:119:3: error: initializer element is not constant .host_features = htole32( ^
I believe these functions were added via bug 6442.
How is that a bug? C does not allow function calls in file scope.
I think it should be valid to do e.g. int a; void foo (int (*x)[htonl (a)]); (where [htonl (a)] is equivalent to [*]). Or, for that matter, char b[sizeof (htonl (a))]; These certainly aren't the only standard functions / macros defined in a way causing problems with that, and maybe a compiler change to allow ({}) outside functions (only giving an error if the resulting expression's value gets used) would be the best fix.
The compiler should allow expression statements in non-evaluated context, but other than that this is not a bug in libc.
Constant expressions cannot contain function calls.