I'm trying to implement a macro ("MY_MACRO"), which stores a string preceded by a 32 bit integer number in a certain section ("my_section").
Example: MY_MACRO(200, "my first string %u %x");
Here are the options I tried and the problems I'm facing with. I would appreciate any help.
(gcc 4.7.3. MIPS cpu)
Option A:
#define MY_MACRO(_num, _string)\
asm volatile(".pushsection .my_section");\
asm volatile(".byte %0, %1, %2, %3" : : "i"((_num >> 24) & 0xFF), "i"((_num >> 16) & 0xFF), "i"((_num >> 8) & 0xFF), "i"(_num & 0xFF)); /* Store the number */ \
asm volatile(".ascii " #_string);\
asm volatile(".popsection");
Compile error (it doesn't occur for each usage of the macro):
c:\Temp\ccpDEDnt.s: Assembler messages:
c:\Temp\ccpDEDnt.s:1024: Warning: .popsection without corresponding .pushsection; ignored
I think the reason is a compiler optimization which changes the instructions order (although each asm instruction is volatile, the compiler is allowed to change the order).
Q: Is there any way to disable the compiler optimizations just for the scope of these lines without #pragma?
This issue led me to find a solution in which the four asm instructions are unified.
Option B:
#define MY_MACRO(_num, _string)\
asm volatile(".pushsection .my_section\n\t" \
".byte %0, %1, %2, %3\n\t" \
".ascii " #_string "\n\t" \
".popsection" \
: : "i"((_num >> 24) & 0xFF), "i"((_num >> 16) & 0xFF), "i"((_num >> 8) & 0xFF), "i"(_num & 0xFF));
Compiler errors:
foo.c:733:13: error: invalid 'asm': operand number missing after %-letter
foo.c:733:13: error: invalid 'asm': operand number out of range
Since the string includes the percent sign (%), the compiler interprets it as an asm operands.
Option C:
#define MY_MACRO(_num, _string)\
asm volatile(".pushsection .my_section\n\t" \
".byte %0, %1, %2, %3\n\t" \
".ascii %4\n\t" \
".popsection" \
: : "i"((_num >> 24) & 0xFF), "i"((_num >> 16) & 0xFF), "i"((_num >> 8) & 0xFF), "i"(_num & 0xFF), "X"(#_string));
Here I tried to pass the string as an operand. I don't even know if it's feasible.
I didn't manage to compile this code.
Option B is the right way, however you will need to double all percent signs (%) occurring in your string because that's interpreted as an operand placeholder in the inline asm.
If you don't particularly care about ordering or inlining, you could also let gcc handle it for you:
struct mystruct
{
int num;
char string[0];
};
#define MY_MACRO(_num, _string)\
{ static struct mystruct entry __attribute__ ((section (".my_section"))) = { _num, _string }; }
Related
I am writing some C code that is for a microcontroller and have come across a curious couple of statements in some generated drivers for a peripheral I am using. Seemingly, a function uint8_t gapm_reset_req_handler (void) is supposed to reset a handler and return a status. The function is seemingly failing in its purpose, which surprises me as it seems simple enough. The relevant code I would like to ask about is this function and that INTERFACE_UNPACK_UINT8 line.
uint8_t gapm_reset_req_handler (void) {
uint8_t u8Operation, u8Status;
INTERFACE_MSG_INIT(GAPM_RESET_CMD, TASK_GAPM);
INTERFACE_PACK_ARG_UINT8(GAPM_RESET);
INTERFACE_SEND_WAIT(GAPM_CMP_EVT, TASK_GAPM);
INTERFACE_UNPACK_UINT8(&u8Operation);
INTERFACE_UNPACK_UINT8(&u8Status);
INTERFACE_MSG_DONE();
if(u8Operation!=GAPM_RESET)
return AT_BLE_FAILURE;
return u8Status;}
These INTERFACE messages are defined in another file, and I am a bit lost at what exactly is supposed to be accomplished by the generated code regarding the use of the double underscore on the ptr variable. Does anyone have any intuition as to what is going on? To me, it looks like some operation on the value that is passed to it but the use of the double underscore confuses me as I thought that was just for macros. Any thoughts are greatly appreciated!
Specific line
#define INTERFACE_UNPACK_UINT8(ptr)\
*ptr = *__ptr++
Full Definition of INTERFACE Code:
#ifndef __INTERFACE_H__
#define __INTERFACE_H__
#include "event.h"
#define INTERFACE_HDR_LENGTH 9
#define INTERFACE_API_PKT_ID 0x05
#define INTERFACE_SEND_BUF_MAX 600
#define INTERFACE_RCV_BUFF_LEN 500
extern uint8_t interface_send_msg[INTERFACE_SEND_BUF_MAX];
void platform_send_lock_aquire(void);
void platform_send_lock_release(void);
#define INTERFACE_MSG_INIT(msg_id, dest_id) \
do{\
uint8_t* __ptr = interface_send_msg;\
uint16_t __len;\
platform_send_lock_aquire();\
*__ptr++ = (INTERFACE_API_PKT_ID);\
*__ptr++ = ((msg_id) & 0x00FF );\
*__ptr++ = (((msg_id)>>8) & 0x00FF );\
*__ptr++ = ((dest_id) & 0x00FF );\
*__ptr++ = (((dest_id)>>8) & 0x00FF );\
*__ptr++ = ((TASK_EXTERN) & 0x00FF );\
*__ptr++ = (((TASK_EXTERN)>>8) & 0x00FF );\
__ptr += 2
#define INTERFACE_PACK_ARG_UINT8(arg)\
*__ptr++ = (arg)
#define INTERFACE_PACK_ARG_UINT16(arg)\
*__ptr++ = ((arg) & 0x00FF);\
*__ptr++ = (((arg) >> 8) & 0x00FF)
#define INTERFACE_PACK_ARG_UINT32(arg) \
*__ptr++ = (uint8_t)((arg) & 0x00FF );\
*__ptr++ = (uint8_t)(( (arg) >> 8) & 0x00FF) ;\
*__ptr++ = (uint8_t)(( (arg) >> 16) & 0x00FF);\
*__ptr++ = (uint8_t)(( (arg) >> 24) & 0x00FF)
#define INTERFACE_PACK_ARG_BLOCK(ptr,len)\
memcpy(__ptr, ptr, len);\
__ptr += len
#define INTERFACE_PACK_ARG_DUMMY(len)\
__ptr += len
#define INTERFACE_PACK_LEN()\
__len = __ptr - &interface_send_msg[INTERFACE_HDR_LENGTH];\
interface_send_msg[7] = ((__len) & 0x00FF );\
interface_send_msg[8] = (((__len)>>8) & 0x00FF);\
__len += INTERFACE_HDR_LENGTH;
#define INTERFACE_SEND_NO_WAIT()\
INTERFACE_PACK_LEN();\
interface_send(interface_send_msg, __len)
#define INTERFACE_SEND_WAIT(msg, src)\
watched_event.msg_id = msg;\
watched_event.src_id = src;\
INTERFACE_PACK_LEN();\
interface_send(interface_send_msg, __len);\
if(platform_cmd_cmpl_wait()){return AT_BLE_FAILURE;}\
__ptr = watched_event.params;\
#define INTERFACE_MSG_DONE()\
platform_send_lock_release();\
}while(0)
#define INTERFACE_UNPACK_INIT(ptr)\
do{\
uint8_t* __ptr = (uint8_t*)(ptr);\
#define INTERFACE_UNPACK_UINT8(ptr)\
*ptr = *__ptr++
#define INTERFACE_UNPACK_UINT16(ptr)\
*ptr = (uint16_t)__ptr[0]\
| ((uint16_t)__ptr[1] << 8);\
__ptr += 2
#define INTERFACE_UNPACK_UINT32(ptr)\
*ptr = (uint32_t)__ptr[0] \
| ((uint32_t)__ptr[1] << 8) \
| ((uint32_t)__ptr[2] << 16)\
| ((uint32_t)__ptr[3] << 24);\
__ptr += 4
#define INTERFACE_UNPACK_BLOCK(ptr, len)\
memcpy(ptr, __ptr, len);\
__ptr += len
#define INTERFACE_UNPACK_SKIP(len)\
__ptr += (len)
#define INTERFACE_UNPACK_DONE()\
}while(0)
void interface_send(uint8_t* msg, uint16_t u16TxLen);
#endif /* HCI_H_ */
*ptr = *__ptr++ is simply a byte copy followed by increasing the source pointer by one. __ptr is a local variable declared inside one of the macros then re-used in the other macros.
Notably, it is bad practice to use identifiers starting with underscore and particularly with two underscore or one underscore + an upper case letter. These are reserved for the compiler and standard lib, and the lib you post does not appear to belong to either. So there is reason to believe it was badly designed.
The following function-like macro nightmare confirms this - this is some horrible code with non-existent type safety and massive potential for undefined behavior upon bitwise arithmetic with signed numbers. People used to write macro crap like this before function inlining became industry standard back in the 1980s-1990s. Although stdint.h was introduced in 1999 so more likely they were just incompetent.
As for what the code does, it is much simpler than it looks. There's just various macros for shoveling data from one data type to another, apparently part of some protocol encoding/decoding. They also seem to make various assumptions about endianess that aren't portable.
Please never use or trust code provided to you by some silicon vendor. They have a very long tradition of employing the absolutely worst programmers in the world. If someone wrote microcontroller code like this in a normal company, they would get fired immediately. Similarly, don't trust the average open source barf posted on Github either.
This is not important and should be quite simple, I just don't understand what I'm doing wrong.
The story behind this is that I'm playing with tinyNeoPixel lib on the attiny85, and I'm trying to dive a bit deeper than I need.
This is traditional ANSI C and I'm using a Raspberry Pi3 for this test, but for this case this should be irrelevant. The sizeof(c) on the printf just shows that 'c' is 4 bytes, as expected.
I'm trying to extract the Red, Green, and Blue part of a color that's stored as a 32 bits number
Obviously I'm failing to return the result as a 1 byte value, can same one please tell me how do I do that ? Just casting to (uint8_t) just produces zero.
Thank you.
pi3:~/src$ cat a.c
#include <stdio.h>
typedef unsigned char uint8_t;
typedef unsigned long int uint32_t;
#define Red(x) (x & 0xff000000)
#define Green(x) (x & 0x00ff0000)
#define Blue(x) (x & 0x0000ff00)
void main()
{
uint32_t c;
uint8_t r,g,b;
c=0xffeecc00;
r=Red(c);
g=Green(c);
b=Blue(c);
printf("%d - %08x - %02x %02x %02x\n", sizeof(c), c, r, g, b);
printf("%d - %08x - %02x %02x %02x\n", sizeof(c), c, Red(c), Green(c), Blue(c));
}
pi3:~/src$ gcc a.c -o a
pi3:~/src$ ./a
4 - ffeecc00 - 00 00 00
4 - ffeecc00 - ff000000 ee0000 cc00
The solution is:
#define Red(x) (((x) & 0xff000000) >> 24)
#define Green(x) (((x) & 0x00ff0000) >> 16)
#define Blue(x) (((x) & 0x0000ff00) >> 8)
With this macros this produces
pi3:~/src$ ./a
4 - ffeecc00 - ff ee cc
4 - ffeecc00 - ff ee cc
as it should.
Thank you guys.
You need to shift as well as mask. That is, try something like
#define Red(x) (((x) & 0xff000000) >> 24)
and similarly for your Green() and Blue() macros.
(Also note that I've added two extra pairs of parentheses to the macro definition, for safety in expansion.)
I'm writing USB report descriptors, which are a sequence of bytes: a tag byte (in which the lower bits tell how many data bytes follow) followed by 0, 1, 2 or 4 data bytes. e.g. to define the logical ranges of an input:
uint8_t report_descriptor[] = {
...
0x15, 0x00, // Logical Minimum (0)
0x26, 0xFF, 0x03, // Logical Maximum (1023)
...
};
Since 0 fits into one byte, we use tag type 0x15 (Logical Minimum with one data byte). But 1023 requires two bytes, so tag type 0x26 (Logical Maximum with two data bytes).
I had hoped to define some macros to make this more readable (and avoid having to comment every line):
uint8_t report_descriptor[] = {
...
LOGICAL_MINIMUM(0),
LOGICAL_MAXIMUM(1023),
...
};
However, I've hit a snag: that macro needs to expand to a different number of elements depending on the value. I don't see any easy way to achieve this. I've tried tricks like value > 255 ? (value & 0xFF, value >> 8) : value, but it always gets expanded to just one byte.
I think the spec allows to just always use the 4-byte tags, but that would be wasteful, so I'd rather not do that.
Is what I'm after possible with the preprocessor?
There is a dirty hack that will achieve the asked functionality. But being a dirty hack, it's unlikely to improve the readability. But it works. First lets define an include file helper.h like this:
#if PARAM > 255
0x26, (PARAM & 0xFF), (PARAM >> 8),
#else
0x15, (PARAM),
#endif
Then in our main we will do:
uint8_t report_descriptor[] = {
#define PARAM 0
#include "helper.h"
#undef PARAM
#define PARAM 1023
#include "helper.h"
#undef PARAM
};
To see it is working here is the test code:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
uint8_t report_descriptor[] = {
#define PARAM 0
#include "helper.h"
#undef PARAM
#define PARAM 1023
#include "helper.h"
#undef PARAM
};
int main(int argc, char** args) {
int i;
for (i=0; i < sizeof(report_descriptor); i++ )
printf("%x\n", report_descriptor[i]);
return 0;
}
and the output is:
15
0
26
ff
3
I don't think that the C preprocessor is powerful enough to do this in a clean way. If you are willing to resort to the M4 macro processor, it can be done fairly easily. M4 should be readily available on the vast majority of GNU/Linux systems and portable implementations should be available for most platforms.
Let's define the M4 macros in a separate file and name it macros.m4.
define(`EXTRACT_BYTE', `(($1 >> (8 * $2)) & 0xFF)')
dnl You probably don't want to define these as M4 macros but as C preprocessor
dnl macros in your header files.
define(`TAG_1_BYTES', `0x15')
define(`TAG_2_BYTES', `0x26')
define(`TAG_3_BYTES', `0x37')
define(`TAG_4_BYTES', `0x48')
define(`EXPAND_1_BYTES', `TAG_1_BYTES, EXTRACT_BYTE($1, 0)')
define(`EXPAND_2_BYTES', `TAG_2_BYTES, EXTRACT_BYTE($1, 1), EXTRACT_BYTE($1, 0)')
define(`EXPAND_3_BYTES', `TAG_3_BYTES, EXTRACT_BYTE($1, 2), EXTRACT_BYTE($1, 1), EXTRACT_BYTE($1, 0)')
define(`EXPAND_4_BYTES', `TAG_4_BYTES, EXTRACT_BYTE($1, 3), EXTRACT_BYTE($1, 2), EXTRACT_BYTE($1, 1), EXTRACT_BYTE($1, 0)')
define(`ENCODE',
`ifelse(eval($1 < 256), `1', `EXPAND_1_BYTES($1)',
`ifelse(eval($1 < 65536), `1', `EXPAND_2_BYTES($1)',
`ifelse(eval($1 < 16777216), `1', `EXPAND_3_BYTES($1)',
`EXPAND_4_BYTES($1)')')')')
Now, writing your C files is straight forward. Put the following code in a file test.c.m4:
include(`macros.m4')
`static unint8_t report_descriptor[] = {'
ENCODE(50),
ENCODE(5000),
ENCODE(500000),
ENCODE(50000000),
`};'
In your Makefile, add the following rule
test.c: test.c.m4 macros.m4
${M4} $< > $#
where M4 is set to the M4 processor (usually m4).
If M4 is run on test.c.m4, it will – omitting some excess white space – produce the following test.c file:
static unint8_t report_descriptor[] = {
0x15, ((50 >> (8 * 0)) & 0xFF),
0x26, ((5000 >> (8 * 1)) & 0xFF), ((5000 >> (8 * 0)) & 0xFF),
0x37, ((500000 >> (8 * 2)) & 0xFF), ((500000 >> (8 * 1)) & 0xFF), ((500000 >> (8 * 0)) & 0xFF),
0x48, ((50000000 >> (8 * 3)) & 0xFF), ((50000000 >> (8 * 2)) & 0xFF), ((50000000 >> (8 * 1)) & 0xFF), ((50000000 >> (8 * 0)) & 0xFF),
};
You'll probably find it more convenient to keep the test.c.m4 file as minimal as possible and #include it in an ordinary C file.
If you don't know M4, you can learn the basics rather quickly. If already using GNU Autoconf, you might find it convenient to use their M4sugar M4 macro library instead of the plain M4 I've used above.
I have some crude generated header from some .dbc files.
Since a few of the messages represent elements from an array the structure is equal and so the generated Macros are equal. Since I fill some array of struct in the code I would like to save effort and use the same macro for all objects, but to ensure the definitions have not changed I would like to test at compile time if the macros are equal.
Example:
#define GET_PATTERN_01_PATTERNPOINT02Y(buf) (0 \
| (uint16)(-(uint16)((buf[7] >> 6) & 0x01) << 15) \
| (uint8)(+(uint8)((buf[6] >> 0) & 0xff) << 0) \
| (uint16)(+(uint16)((buf[7] >> 0) & 0x7f) << 8) \
)
#define GET_PATTERN_02_PATTERNPOINT04Y(buf) (0 \
| (uint16)(-(uint16)((buf[7] >> 6) & 0x01) << 15) \
| (uint8)(+(uint8)((buf[6] >> 0) & 0xff) << 0) \
| (uint16)(+(uint16)((buf[7] >> 0) & 0x7f) << 8) \
)
#if GET_PATTERN_01_PATTERNPOINT02Y != GET_PATTERN_02_PATTERNPOINT04Y
# error blah
#endif
Is this Possible?
If there is some solution in C++ that may also help. But the macros are fixed.
This is a horrible hack, but seems to work for your example for GCC and C11 at least:
#include <assert.h>
#include <string.h>
...
#define STRINGIFY(x) STRINGIFY_(x)
#define STRINGIFY_(x) #x
#define ASSERT_SAME(m1, m2) \
static_assert(strcmp(STRINGIFY(m1(xxx)), STRINGIFY(m2(xxx))) == 0, \
#m1"() and "#m2"() differ!")
ASSERT_SAME(GET_PATTERN_01_PATTERNPOINT02Y, GET_PATTERN_02_PATTERNPOINT04Y);
You might need to pass -std=c11 or -std=gnu11, though the latter shouldn't be needed here.
Explanation:
STRINGIFY(x) returns the expansion of x as a string literal. We need to do the stringification in two steps using STRINGIFY_() because # suppresses macro expansion. (With one step we'd get "<x>" instead of "expanded version of <x>".)
GCC has a built-in version of strcmp() (__builtin_strcmp()) which is used here. It just happens to be able to compare constant strings at compile-time. The code breaks if you pass -fno-builtin (unless you explicitly use __builtin_strcmp()).
static_assert is a C11 compile-time assertion.
With the three ingredients above we can stringify the expanded macros (passing some dummy token that's likely to be unique for the argument) and compare the strings at compile-time.
Yes, this is a hack...
In C++11 there are safer ways to compare strings at compile time -- see e.g. this answer.
As a side note, you could do this at run-time too with zero overhead for GCC and Clang. (The version above won't work for Clang as it's pickier about strcmp(...) == 0 not being an integer constant expression as required by static_assert.) A run-time check like
if (strcmp(STRINGIFY(m1(xxx)), STRINGIFY(m2(xxx))) != 0) {
*report error and exit*
}
gets completely optimized out when the macros are equal. Not even the strings are kept in the read-only data segment (just checked). It's a more robust approach if you can live with having to run the program to discover the problem.
It possible to do this a bit better by using variadic macros to do the stringification:
#define STRINGIFY_VARIADIC(...) #__VA_ARGS__
#define EXPAND_AND_STRINGIFY_VARIADIC(...) STRINGIFY_VARIADIC (__VA_ARGS__)
#define STATIC_ASSERT_IDENTICAL_EXPANSIONS(macro_a, macro_b) \
_Static_assert ( \
( \
__builtin_strcmp ( \
EXPAND_AND_STRINGIFY_VARIADIC (macro_a), \
EXPAND_AND_STRINGIFY_VARIADIC (macro_b) ) \
== 0 \
), \
"expansions of " #macro_a " and " #macro_b " differ" )
This has two advantages: it works with macros which expand to tuples
(e.g. #define FOO thing1, thing2), and it works with macros which take
arguments (without a dummy token like xxx in the other solution). Note that
the final expansions are compared, not the full expansion histories.
So given these #defines:
#define FOO foo
#define BAR bar
#define ARG_DOUBLER(arg) arg, arg
#define ARG_ITSELF(arg) arg
#define OTHER_ARG_DOUBLER(arg) ARG_ITSELF (arg), ARG_ITSELF (arg)
#define SECOND_ARG_NUKER(arg1, arg2) arg1
All of these will trigger a compile-time error:
STATIC_ASSERT_IDENTICAL_EXPANSIONS (FOO, BAR);
STATIC_ASSERT_IDENTICAL_EXPANSIONS (ARG_DOUBLER (x), ARG_DOUBLER (y));
STATIC_ASSERT_IDENTICAL_EXPANSIONS (x, ARG_ITSELF (y));
STATIC_ASSERT_IDENTICAL_EXPANSIONS (SECOND_ARG_NUKER (x, y), y);
While of these will compile ok:
STATIC_ASSERT_IDENTICAL_EXPANSIONS (FOO, foo);
STATIC_ASSERT_IDENTICAL_EXPANSIONS (ARG_DOUBLER (x), ARG_DOUBLER (x));
STATIC_ASSERT_IDENTICAL_EXPANSIONS (x, ARG_ITSELF (x));
STATIC_ASSERT_IDENTICAL_EXPANSIONS (SECOND_ARG_NUKER (x, y), x);
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I'm facing following problem.
The macro
#define uswap_32(x) \
((((x) & 0xff000000) >> 24) | \
(((x) & 0x00ff0000) >> 8) | \
(((x) & 0x0000ff00) << 8) | \
(((x) & 0x000000ff) << 24))
get's following number as argument x = 0x49074808
Why does my program break/resets here??
Thx
EDIT:
Description of my real application:
I have a bootloader sitting at flash start address 0x08000000U going till 0x08004000U.
After the bootloader there is a uImage header(taken from uboot) in flash, with size 0x40.
In my application, I just want to check, if there is actually a correct uImage header, because I have two bootloader versions. One can handle images of type uImage and the other one can't. In the last case, after the bootloader application there is no uImage header at all, there is application code!
In the application I just want to check the header crc:
#define UIMAGE_FLASH_ADDRESS (0x08004000U)
image_header_t *header;
header = (image_header_t *) UIMAGE_FLASH_ADDRESS;
if (image_check_hcrc(header))
/* do something...*/
static int image_check_hcrc(const image_header_t *hdr)
{
uint32_t hcrc;
uint32_t len = image_get_header_size();
image_header_t header;
/* Copy header so we can blank CRC field for re-calculation */
memcpy(&header, (char *)hdr, image_get_header_size());
header.ih_hcrc = 0; // byte order independent
hcrc = crc32(0, (unsigned char *)&header, len);
return hcrc == image_get_hcrc(hdr);
}
The call for uswap_32() happens in the last line of above function:
#define uswap_32(x) \
((((x) & 0xff000000) >> 24) | \
(((x) & 0x00ff0000) >> 8) | \
(((x) & 0x0000ff00) << 8) | \
(((x) & 0x000000ff) << 24))
# define cpu_to_be32(x) uswap_32(x)
# define be32_to_cpu(x) uswap_32(x)
#define uimage_to_cpu(x) be32_to_cpu(x)
#define cpu_to_uimage(x) cpu_to_be32(x)
#define image_get_hdr_l(f) \
static inline uint32_t image_get_##f(const image_header_t *hdr) \
{ \
return uimage_to_cpu(hdr->ih_##f); \
}
image_get_hdr_l(magic) /* image_get_magic */
image_get_hdr_l(hcrc) /* image_get_hcrc */
image_get_hdr_l(time) /* image_get_time */
image_get_hdr_l(size) /* image_get_size */
image_get_hdr_l(load) /* image_get_load */
image_get_hdr_l(ep) /* image_get_ep */
image_get_hdr_l(dcrc) /* image_get_dcrc */
#define image_get_hdr_b(f) \
static inline uint8_t image_get_##f(const image_header_t *hdr) \
{ \
return hdr->ih_##f; \
}
image_get_hdr_b(os) /* image_get_os */
image_get_hdr_b(arch) /* image_get_arch */
image_get_hdr_b(type) /* image_get_type */
image_get_hdr_b(comp) /* image_get_comp */
It is a good idea to assign x to a local variable within a macro. Otherwise, if an expression is passed as an argument to the macro, it will be evaluated 4 times. For example, uswap(2+3), or even worse, uswap(some_func(x)).
Second issue - you need to add explicit UL type modifier for the constants. Here is a safer version of the macro:
#define uswap_32(x) ({\
uint32_t _x = (x);\
(uint32_t)(\
((_x & 0xff000000UL) >> 24) | \
((_x & 0x00ff0000UL) >> 8) | \
((_x & 0x0000ff00UL) << 8) | \
((_x & 0x000000ffUL) << 24)); \
})