This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

__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;
}

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]