1

是否len已正确初始化且set_array通话安全?

void object_copy (Object* self, Object* obj) {
    int len;
    object_set_array (self, object_get_array (obj, &len), len);
}

如果没有,你会推荐什么?

4

5 回答 5

6

否 - 函数调用的参数没有定义的评估顺序。

即使调用 必须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
}
于 2010-01-22T23:48:21.497 回答
1

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);
}
于 2010-01-22T23:48:20.903 回答
0

您在初始化之前将len值传递给调用。object_set_array()所以这是错误的,一个好的编译器会警告这一点。该变量将包含一个随机值,因此代码不会崩溃,但它不会执行您可能想要的操作。

于 2010-01-22T23:47:54.040 回答
0

如果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将被初始化,但它不安全。

希望这会有所帮助,最好的问候,汤姆。

于 2010-01-22T23:52:35.620 回答
0

这也将起作用:

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将被设置为正确的值。

于 2010-01-23T00:07:52.527 回答