gpt4 book ai didi

c - gcc 优化掉复合语句

转载 作者:太空宇宙 更新时间:2023-11-04 06:30:48 24 4
gpt4 key购买 nike

我在为 C 中的通用可调整大小 vector 实现 push_back 运算符时遇到问题。为了通用性,我需要使用 void 指针作为参数,但实际上我想直接给它赋值。

当我用 gcc -o t test.c -std=c99 编译下面的代码时,它按我的预期打印了 10。当我将 -O1(或更高)添加到编译选项时,程序打印 0

我认为问题出在 smemcpy 代码中,因为当我用 memcpy 替换它时,我不再有这个问题。

简化代码:

#include <stdio.h>
#include <stdlib.h>

#define get_pointer(value) ({ __typeof__(value) tmp = value; &tmp; })

// copy from src to dst byte by byte
void* smemcpy(void* dst, void const * src, size_t len) {
char * pdst = (char *) dst;
char const * psrc = (char const *) src;

while (len--) {
*pdst++ = *psrc++;
}

return (dst);
}


int main() {
void* container = malloc(sizeof(int));

// copy a 10 into the container via a temporary pointer
smemcpy(container, get_pointer(10), sizeof(int));

printf("%d\n", ((int*)container)[0]);

return 0;
}

在此先感谢您的帮助,

B

最佳答案

get_pointer 的定义使用表达式中的语句,即GCC extension .其语义几乎没有记录,并且没有理由相信在语句表达式中声明的对象的存储持续时间在语句的评估之外仍然存在。

因此,在准备对 smemcpy 的调用时,编译器可以通过创建对象 tmp 来评估 get_pointer,产生其地址作为值语句表达式,并销毁对象 tmp。然后将不再存在的对象的现在无效地址传递给 smemcpy,它复制无效数据,因为用于 tmp 的空间已被重新用于其他目的。

当使用memcpy时,代码可能会工作,因为memcpy是GCC已知的一个特殊函数,GCC以各种特殊方式对其进行了优化。

复合文字应该可以工作; C 标准指定函数体内的复合文字具有与封闭 block 关联的自动存储持续时间。如果我们按如下方式定义 get_pointer,封闭 block 包括整个 smemcpy 调用:

#define get_pointer(value) (& (__typeof__(value)) { value })

关于c - gcc 优化掉复合语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20777555/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com