This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
__bswap_constant_64() macro causing warnings with gcc -pedantic
- From: Olivier Favre <olivier at yakaz dot com>
- To: libc-alpha at sourceware dot org
- Date: Fri, 23 Dec 2011 15:28:30 +0100
- Subject: __bswap_constant_64() macro causing warnings with gcc -pedantic
Greetings,
When using the __bswap_constant_64() macro and compiling with -pedantic,
gcc generates 8 of the following warning:
$ gcc -pedantic longlong_pedantic_byteswap_warning.c
longlong_pedantic_byteswap_warning.c: In function ‘main’:
longlong_pedantic_byteswap_warning.c:7:42: warning: use of C99
long long integer constant [-Wlong-long]
And using g++ you get the following variant, also 8 times :
longlong_pedantic_byteswap_warning.c:7:42: warning: use of C++0x
long long integer constant [-Wlong-long]
(see attached source file)
Here is the offending code part in bits/byteswap.h:
#if defined __GNUC__ && __GNUC__ >= 2
/* Swap bytes in 64 bit value. */
# define __bswap_constant_64(x) \
((((x) & 0xff00000000000000ull) >> 56) \
| (((x) & 0x00ff000000000000ull) >> 40) \
| (((x) & 0x0000ff0000000000ull) >> 24) \
| (((x) & 0x000000ff00000000ull) >> 8) \
| (((x) & 0x00000000ff000000ull) << 8) \
| (((x) & 0x0000000000ff0000ull) << 24) \
| (((x) & 0x000000000000ff00ull) << 40) \
| (((x) & 0x00000000000000ffull) << 56))
I think __extension__ should be used before the "0x...ull" constants
to give gcc a rest.
However I did not succeed in finding a good place for it. So I removed
an L in the suffix.
I don't fully understand how long long is supposed to be different
from long, but looking at stdint.h:
# if __WORDSIZE == 64
typedef long int int64_t;
# else
__extension__
typedef long long int int64_t;
# endif
suggests using an #if in __bswap_constant_64 definition.
Here is a proposition:
#if defined __GNUC__ && __GNUC__ >= 2
/* Swap bytes in 64 bit value. */
# if __WORDSIZE == 64
# define __UINT64(x) x ## ul
# else
# define __UINT64(x) x ## ull
# endif
# define __bswap_constant_64(x) \
((((x) & __UINT64(0xff00000000000000)) >> 56) \
| (((x) & __UINT64(0x00ff000000000000)) >> 40) \
| (((x) & __UINT64(0x0000ff0000000000)) >> 24) \
| (((x) & __UINT64(0x000000ff00000000)) >> 8) \
| (((x) & __UINT64(0x00000000ff000000)) << 8) \
| (((x) & __UINT64(0x0000000000ff0000)) << 24) \
| (((x) & __UINT64(0x000000000000ff00)) << 40) \
| (((x) & __UINT64(0x00000000000000ff)) << 56))
By the way, here's my configuration:
$ uname -a
Linux Ofavre-Desktop 2.6.32-5-amd64 #1 SMP Tue Jun 14 09:42:28 UTC
2011 x86_64 GNU/Linux
$ lsb_release -a
No LSB modules are available.
Distributor ID: Debian
Description: Debian GNU/Linux unstable (sid)
Release: unstable
Codename: sid
I'm using eglibc-2.13-21, but I can see that bits/byteswap.h in glibc
has the described flaw, as of 2011/12/23:
http://sourceware.org/git/?p=glibc.git;a=blob_plain;f=bits/byteswap.h;hb=70c6c246a2758fcdc63536d2c7855a80e58613c6
Regards,
--
Olivier Favre
www.yakaz.com
#include <stdint.h>
#include <endian.h>
int main()
{
/* generates 8 -Wlong-long warnings! */
uint64_t value = __bswap_constant_64(0ul);
/* (mute -Wunused-param warning) */
(void)value;
return 0;
}