Search code examples
cmacrosx86-64endianness

define a macro that converts values between byte order


I want to create a macro that converts unsigned value conv to the opposite byte order of the current CPU. When not in a macro, it works well but let's say I want to do that as a macro. The compiler throws me an implict decleration when I try to use the macro. Take in mind that cpu_to_be32 and friends is a kernel-space functions, afaik at least.

#define be32_or_le32(conv)  do { #ifdef __LITTLE_ENDIAN \
            conv = cpu_to_be32(conv); \
        #elif __BIG_ENDIAN \
            conv = cpu_to_le32(conv); \
        #endif } while (0)

u32 x = 0x12345678;

/* Convert the CPU's default byteorder to the opposite one */
be32_or_le32(x); /* Implict decleration */

Update: The answer below works really well but only without the do {} while (0), why when do.. added an error is thrown?

#ifdef __LITTLE_ENDIAN
    #define be32_or_le32(conv) do { conv = cpu_to_be32(conv); } while (0)
#elif __BIG_ENDIAN
    #define be32_or_le32(conv) do { conv = cpu_to_le32(conv); } while (0)
#endif

int __init sys_kernelmod_init(void)
{
    u32 conv;
    u32 x = 0x12345678;

    /* Convert the CPU's default byteorder to the opposite one */
    conv = be32_or_le32(x);
    ...
}

Solution

  • You cannot have preprocessor conditionals inside the macro expansion text.

    Switch the structure to:

    #ifdef __LITTLE_ENDIAN
    #define be32_or_le32(conv) do { conv = cpu_to_be32(conv); } while (0)
    #elif __BIG_ENDIAN
    #define be32_or_le32(conv) do { conv = cpu_to_le32(conv); } while (0)
    #endif