c - 在 C 中交换指针地址

标签 c pointers swap

我需要在 C 中对两个指针进行超高性能交换(地址,而不是它们指向的内容)。我知道地址是对齐的(16 的倍数)并且是连续的,我已经检查过这在每次执行中都会保留。代码如下:

Nodo a __attribute__((aligned(8))), b __attribute__((aligned(4)));
Nodo *nodo_superior __attribute__((aligned(4)));
nodo_superior = &a;
Nodo * nodo_actual __attribute__((aligned(4)));
nodo_actual=&b;
printf("%ld %ld\n", nodo_superior, nodo_actual);

控制台上的结果如下(请注意第一个地址应该“过度”对齐,以便下一个方法起作用):

140594404335200 140594404335216

现在要交换地址,我想更改每个指针的第 5 位:

nodo_superior ^= 16; 
nodo_actual ^= 16;

但是,不幸的是,C 编译器不允许这样做,因为整数不能与指针值混合:这是错误,而不是警告。如果我尝试将指针包含在这样的 union 中:

union {
    Nodo * nodo_actual;
    int local_int;
} na;

想做一个这样的任务:

na.local_int ^= 16;

那么性能会下降,因为(我想)编译器不能对 nodo_actual 应用/推断优化,如果它在一个 union 中。 有什么想法可以强制编译器按照我的意愿行事吗?当然,我可以更改生成的汇编程序,但我认为这不是一个好的选择,

最佳答案

如果你想切换每个指针的第 5 位,你可以这样写:

nodo_superior = (Nodo *)((uintptr_t)nodo_superior ^ 16);

uintptr_t 是一种整数类型,(如果存在)保证能够保存指针值而不会丢失信息。

这是通过平面内存模型上的明显同构来完成的,因此它应该适合您(尽管先测试一下看看)。

此外,您应该使用 %p 来打印指针,而不是 %ld ,这会导致未定义的行为。打印 uintptr_t see here

关于c - 在 C 中交换指针地址,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30891219/

相关文章:

c - 使用 C 验证文件中的登录凭据

c - 从文件中读取,输出只显示一行

c++ - 为什么仅当我的容器包含32个以上元素时,std::sort才会调用swap?

linux - Linux 内核如何交换文件映射页?

循环引用和低级汇编

c - 如何将数据通过管道传输到在 Linux 中调用 scanf() 和 read() 的程序

C++ - 使指向父类(super class)的指针与函数中的子类参数匹配

c - float arrayName[][] 和 float (* arrayNamePointer)[] 有什么区别

c++ - 将数组的地址传递给 C++ 中的函数

linux - 我们需要禁用 riak 交换吗?