我在一些遗留的C代码中遇到了以下内容:
typedef struct _somestruct_ {
/* .... */
} SomeStruct_t
static void do_one_thing(SomeStruct_t *pInput){
/* Do some read-only stuff with pInput */
}
static void do_many_thing(SomeStruct_t input){
do_one_thing(&input);
}
C实际上是否允许这样做,即使实际修改do_one_thing
以写入pInput
,事情可能会爆发吗?
答案 0 :(得分:2)
这是完全合法的C代码。代码do_one_thing(&input)
只是将参数的地址传递给函数do_one_thing
。这没什么不对。
如果do_one_thing
写入pInput
,这甚至都不是问题。地址有效并指向可变值。进行更新没有任何问题。考虑
typedef struct _somestruct_ {
int field;
} SomeStruct_t
static void do_one_thing(SomeStruct_t *pInput){
// Completely legal
pInput->field = 42;
}
static void do_many_thing(SomeStruct_t input){
do_one_thing(&input);
}
答案 1 :(得分:1)
是C会允许此操作,do_many_thing
会将SomeStruct_t
的副本作为input
传递,然后您将地址传递给do_one_thing
,该地址可以自由读取或写入到结构。 do_many_thing
的调用者不会看到对传递的结构执行任何更改。
答案 2 :(得分:0)
这是完全合法的代码。如果do_one_thing写入pInput的数据,它也不会爆炸。如果程序员意识到在do_many_thing结束时do_one_thing所做的更改已经消失,那么这也是完全有效的。
答案 3 :(得分:0)
您基本上是将指针传递给SomeStruct_t input
的值。 SomeStruct_t input
是堆栈上的值,do_one_thing
将修改堆栈值指针,但do_many_thing
的调用者不会看到任何更改。
答案 4 :(得分:0)
C没有通过引用传递,因此这种将指针传递给变量的方法是实现相同语义的唯一方法。
许多其他语言允许您直接通过引用传递。例如,在C ++中你可以这样做:
static void do_one_thing(SomeStruct_t& Input){
Input.foo++;
}
然后当你调用这个函数时,你会这样做:
do_one_thing(input);
但如果没有语言的这种帮助,你唯一的选择就是指针。
答案 5 :(得分:0)
您的代码清单可能不完整,因此无法确切知道,但就目前来看,它看起来并不会“爆炸”。
do_many_thing
收到一些结构的副本input
。然后,您可以通过将此副本传递到do_one_thing
来修改此副本。除非你依赖该副本没有改变,否则一切都不会发生。此外,do_many_thing
的来电者不会看到传入SomeStruct_t
的更改,因此即使在较高级别也不会有副作用。