【发布时间】:2019-03-25 14:37:24
【问题描述】:
这是我的演示代码:
#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 行出现未初始化错误。
我确定这是由于我的理解存在差距,但对我来说,两个不同的 WORK 分支在操作上应该基本相同,所以我不确定误解来自哪里。
这是使用 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;
}
【问题讨论】:
-
为什么你认为两个版本应该相同?这正是“按值传递”和“按引用/指针传递”之间的区别
-
您可以将其简化为
void set_x (int* ptr) { if(foo) { *ptr = 5; } }。当 foo 为零时,ptr 指向的任何东西都不会受到影响并保持为 0,这很奇怪吗?
标签: c pass-by-reference dereference