gpt4 book ai didi

c - 当我将 gcc 与 -O1 优化一起使用时。数组数据初始化被忽略,当我尝试使用数组时,我最终得到未初始化的数据

转载 作者:行者123 更新时间:2023-12-04 12:12:42 24 4
gpt4 key购买 nike

使用 gcc 7.4.0 并使用 -O1 优化标志编译此示例程序,正在优化数组“cap”内设置的数据,留下未初始化的数据。

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

#define CAP_TYPE_1 0x0003
#define CAP_TYPE_2 0x0004
#define CAP_COUNT 2

#define CAP2_CIP_1 0x0001
#define CAP2_CIP_2 0x0002
#define CAP2_CIP_COUNT 2
static uint16_t cap_2_cips[CAP2_CIP_COUNT] = { CAP2_CIP_1, CAP2_CIP_2 };

#define CAP1_ALG_1 0x0010
#define CAP1_ALG_COUNT 1
static uint16_t cap_1_algs[CAP1_ALG_COUNT] = { CAP1_ALG_1 };

typedef struct optests_cap_1
{
uint16_t count;
uint16_t len;
uint16_t *alg;
char *buf;
} optests_cap_1_t;

typedef struct optests_cap_2
{
uint16_t count;
uint16_t *cip;
} optests_cap_2_t;

typedef struct optests_cap
{
uint16_t type;
uint16_t size;
uint16_t flag;
void *data;
} optests_cap_t;

typedef struct optests_caps
{
uint32_t count;
optests_cap_t *structs;
} optests_caps_t;

static int populate_structs(optests_caps_t *caps)
{
optests_cap_1_t *cap_1;
optests_cap_2_t *cap_2;

optests_cap_t cap[CAP_COUNT];

cap_2 = (optests_cap_2_t*)malloc(sizeof(optests_cap_2_t));
cap_2->count = CAP2_CIP_COUNT;
cap_2->cip = cap_2_cips;

cap[0].type = CAP_TYPE_2;
cap[0].size = 6;
cap[0].flag = 0;
cap[0].data = cap_2;

cap_1 = (optests_cap_1_t*)malloc(sizeof(optests_cap_1_t));
cap_1->count = CAP1_ALG_COUNT;
cap_1->len = 4;
cap_1->alg = cap_1_algs;
cap_1->buf = "ABCD";

cap[1].type = CAP_TYPE_1;
cap[1].size = 6 + cap_1->len;
cap[1].flag = 42;
cap[1].data = cap_1;

caps->count = CAP_COUNT;
caps->structs = cap;

return 0;

}


int main(void)
{
optests_caps_t caps;
memset(&caps, 0, sizeof(optests_cap_t));

populate_structs(&caps);

printf("cap_count = %u\n", caps.count);
for(int i = 0; i < caps.count; i++)
{
printf("Type: %u\n", caps.structs[i].type);
printf("Size: %u\n", caps.structs[i].size);
printf("Flag: %u\n", caps.structs[i].flag);
}
/* Free the memory */

}

编译代码:

gcc -O1 -o optest_O1 optest.c
gcc -O0 -o optest_O0 optest.c
gcc -o optest optest.c

输出是这样的:

$ ./optest
cap_count = 2
Type: 4
Size: 6
Flag: 0
Type: 3
Size: 10
Flag: 42
$ ./optest_O0
cap_count = 2
Type: 4
Size: 6
Flag: 0
Type: 3
Size: 10
Flag: 42
$ ./optest_O1
cap_count = 2
Type: 2464
Size: 22561
Flag: 32596
Type: 2000
Size: 22624
Flag: 32596

Valgrind 在运行优化的二进制文件时报告以下内容:

$ valgrind --tool=memcheck --leak-check=yes ./optest_O1



==7316== error calling PR_SET_PTRACER, vgdb might block
cap_count = 2
==7316== Use of uninitialised value of size 8
==7316== at 0x4E9486B: _itoa_word (_itoa.c:179)
==7316== by 0x4E97F0D: vfprintf (vfprintf.c:1642)
==7316== by 0x4F6E2EB: __printf_chk (printf_chk.c:35)
==7316== by 0x10871D: main (in /opttest/optest_O1)
==7316==
==7316== Conditional jump or move depends on uninitialised value(s)
==7316== at 0x4E94875: _itoa_word (_itoa.c:179)
==7316== by 0x4E97F0D: vfprintf (vfprintf.c:1642)
==7316== by 0x4F6E2EB: __printf_chk (printf_chk.c:35)
==7316== by 0x10871D: main (in /opttest/optest_O1)
==7316==
==7316== Conditional jump or move depends on uninitialised value(s)
==7316== at 0x4E98014: vfprintf (vfprintf.c:1642)
==7316== by 0x4F6E2EB: __printf_chk (printf_chk.c:35)
==7316== by 0x10871D: main (in /opttest/optest_O1)
==7316==
==7316== Conditional jump or move depends on uninitialised value(s)
==7316== at 0x4E98B4C: vfprintf (vfprintf.c:1642)
==7316== by 0x4F6E2EB: __printf_chk (printf_chk.c:35)
==7316== by 0x10871D: main (in /opttest/optest_O1)
==7316==
Type: 2464



如果我将 gcc -fno-tree-dce -fno-tree-dse 标志与 -O1 一起使用,我会得到正确的输出。我想了解 GCC 在做什么,这是一个 gcc 错误,还是有不同的方式来编写不会触发此问题的上述代码?

最佳答案

gcc 很好,您的代码有问题。

static int populate_structs(optests_caps_t *caps)
{
// ...
optests_cap_t cap[CAP_COUNT];
// ...
caps->structs = cap;
}

cap 是函数 populate_structs 的局部变量,因此在该函数返回后,任何对 caps->structs 指向的内存的进一步访问> 是未定义的行为。

也许您想将 cap 声明为静态的,或者使用 malloc 为其分配一些内存。

关于c - 当我将 gcc 与 -O1 优化一起使用时。数组数据初始化被忽略,当我尝试使用数组时,我最终得到未初始化的数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60020983/

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