是否len
已正确初始化且set_array
通话安全?
void object_copy (Object* self, Object* obj) {
int len;
object_set_array (self, object_get_array (obj, &len), len);
}
如果没有,你会推荐什么?
否 - 函数调用的参数没有定义的评估顺序。
即使调用 必须object_get_array()
在调用 之前发生object_set_array()
,编译器计算并传递给参数的值object_set_array()
也len
可以在编译器调用 之前完成object_get_array()
。
我不确定object_set_array()
调用的第二个参数是什么 - 也许您想使用逗号运算符:
void object_foo (Object* self, Object* obj) {
int len;
object_set_array (self, (object_get_array (obj, &len), len));
}
哪个会起作用,但会令人困惑,我不建议这样做。
我想你想要的是:
void object_foo (Object* self, Object* obj) {
int len;
object_get_array (obj, &len); // get the length from obj
object_set_array (self, len)); // set the len for self
}
object_set_array()
不可以。在计算第二个参数 ( ) 之前,可能会计算第三个参数并将其压入堆栈object_get_array()
。
可能你想要
void object_copy (Object* self, Object* obj) {
int len;
/* I'm just guessing as to the return type */
Object *pObj = object_get_array(obj, &len);
object_set_array (self, pObj, len);
}
您在初始化之前将len
值传递给调用。object_set_array()
所以这是错误的,一个好的编译器会警告这一点。该变量将包含一个随机值,因此代码不会崩溃,但它不会执行您可能想要的操作。
如果object_get_array
失败,则len
可能无法初始化。在调用之前最好object_get_array
先调用object_set_array
,这样你就可以测试调用是否有效。
这是一个示例代码,请注意,我不知道object_get_array
返回什么,因此我使用了 avoid *
以便于解释:
无效*对象; obj = object_get_array(obj, &len); if (obj != NULL) object_set_array(self, obj, len);
您编写的代码很危险,但使用这样的捷径可能会导致您认为它object_set_array
已经失败而不是object_get_array
. 你必须自己判断它是否会失败,我总是假设代码失败,以便我可以采取保护措施,你的方法会有所不同,某些快捷方式是可以的,这个不是!
即使 C 代码是从左到右执行的,按照表达式的计算顺序(取决于编译器和编译的代码),如果函数有效,那么是的,len
将被初始化,但它不安全。
希望这会有所帮助,最好的问候,汤姆。
这也将起作用:
ARRAY object_get_array (Object* self, int* len);
void object_set_array (Object* self, ARRAY array, const int* len);
// ...
void object_copy (Object* self, Object* obj) {
int len;
object_set_array (self, object_get_array (obj, &len), &len);
}
因为调用 toobject_get_array()
将始终在调用 to 之前进行评估object_set_array()
,此时len
将被设置为正确的值。