这是我的演示代码:
#include <stdio.h>
#define WORK 0
typedef struct FooStruct {
int x;
} FooStruct;
void setX(FooStruct *foo_ptr) {
FooStruct foo = *foo_ptr;
if (WORK) {
foo_ptr->x = 10;
} else {
foo.x = 10;
}
}
FooStruct makeFoo() {
FooStruct foo = { 0 };
setX(&foo);
return foo;
}
int main(void) {
FooStruct foo = makeFoo();
printf("X = %d\n", foo.x);
return 0;
}
如果WORK被定义为1,则代码按预期执行并打印“X=10”。
但是,如果WORK设置为0,它将打印“X=0”,或者如果FooStruct不是默认初始化的(即将FooStruct foo={};更改为FooStruct foo;),valgrind将在printf行上抛出一个值未初始化的错误。
我确信这是因为我的理解有差距,但对我来说,这两个不同的工作部门在运作上应该是完全相同的,所以我不确定误解是从哪里来的。
这是用gcc 8.2.0编译的,有/没有valgrind,结果相同。
=======================
编辑:
简化示例:
#include <stdio.h>
#define WORK 0
void setX(int *x_ptr) {
if (WORK) {
*x_ptr = 5;
} else {
int x = *x_ptr;
x = 5;
}
}
int main(void) {
int x = 0;
setX(&x);
printf("X = %d\n", x);
return 0;
}
最佳答案
当您#define WORK 0
时,代码似乎也按预期工作如果在结构的副本中设置成员,则不应期望修改原始成员。
你有:
void setX(FooStruct *foo_ptr) {
FooStruct foo = *foo_ptr;
if (WORK) {
foo_ptr->x = 10; // Modify the structure pointed to by foo_ptr
} else {
foo.x = 10; // Modify the local copy of the structure
}
}
因为你做了一个MCVE(Minimal, Complete, Verifiable Example-谢谢!),对
setX()
中结构的修改副本没有任何操作。