【发布时间】:2015-03-30 19:31:43
【问题描述】:
采用类型的交换宏是众所周知的。
#define SWAP(type, a_, b_) do { \
type SWAP, *a = &(a_), *b = &(b_); \
SWAP = *a; \
*a = *b; \
*b = SWAP; \
} while (0)
还有: Macro SWAP(t,x,y) exchanging two arguments of type t
是否可以在...的同时实现此功能
- 可移植(没有特定于编译器的
typeof) - 不使用
memcpy等函数调用
(不能保证得到优化,至少在我的测试中没有)
我想出了一个有缺陷的方法,它使用了一个结构体,定义为输入的大小。
#define SWAP(a_, b_) do \
{ \
struct { \
char dummy_data[sizeof(a_)]; \
} SWAP, *a = (void *)(&(a_)), *b = (void *)(&(b_)); \
/* ensure sizes match */ \
{ char t[(sizeof(a_) == sizeof(*a)) ? 1 : -1]; (void)t; } \
/* check types are compatible */ \
(void)(0 ? (&(a_) == &(b_)) : 0); \
SWAP = *a; \
*a = *b; \
*b = SWAP; \
} while (0)
...但是如果临时 struct 被编译器填充,它可能会失败 (取决于 GCC 的 __packed__ 会起作用,但它不再可移植)
它也可能有对齐问题取决于架构。
【问题讨论】:
-
有趣的问题,但为什么?
-
为什么没有
memcpy()但分配没问题? -
由于别名冲突,您的方法也会产生未定义的行为。
-
struct只有一个字段永远不会有填充,第一个字段保证在struct的起始地址。 -
This 是我对这个问题最喜欢的答案。我很想选择这个线程作为重复线程,它并没有真正添加任何新内容,除非您可以以良好基准的形式发布证明,证明
memcpy版本存在问题。
标签: c c-preprocessor c89