gpt4 book ai didi

更改 const 对象 - 没有警告?另外,在什么情况下是 UB?

转载 作者:太空狗 更新时间:2023-10-29 16:56:41 26 4
gpt4 key购买 nike

为什么下面的代码没有警告?

int deserialize_students(const Student *dest, const int destCapacityMax)
{
FILE *ptr_file;
int i=0;


ptr_file =fopen("output.txt","r");
if (!ptr_file)
return -1;

if(destCapacityMax==0)
return -2;

while (!feof (ptr_file))
{
fscanf (ptr_file, "%d", &dest[i].id); // UB?
fscanf (ptr_file, "%s", dest[i].name);
fscanf (ptr_file, "%d", &dest[i].gender);
i++;

if(i==destCapacityMax)
return 0;

}
fclose(ptr_file);
return 0;
}

我是这样调用它的:

Student students[5];
deserialize_students(students,5);

我还有以下问题:我做了未定义的行为吗?注意:

  • 我认为传递 students 很好,因为函数需要 const Student* 而我可以传递非 const。对吧?
  • 但是当我在 fscanf 中修改该对象时,是否触发了 UB?或者这取决于 students 是否首先被声明为 const(在该函数之外)?

最佳答案

您的代码中没有未定义的行为。

调用者传递的是一个可变对象。所以直接或通过显式转换修改它都可以:

int func(const int *p) {
int *q = (int*)p;
*q = 5;
}

只要传递给 func() 的对象是可变的,就可以(可能是不明智但合法的方式)。

但是如果传递的对象是 const 限定的,那么它将是未定义的行为。所以在您的情况下,它不是未定义。

限定符 const 只是一个约定,函数不应该修改 dest。它与对象的实际可变性无关。因此,修改 const 限定符是否调用 UB 取决于传递给的对象是否具有任何此类限定符。

至于警告,GCC (5.1.1) 警告:

int func(const int *p) {
fscanf(stdin, "%d", p);
}

与:

warning: writing into constant object (argument 3) [-Wformat=]

可能 VS 没有识别出 fscanf() 修改了对象。但是 C 标准只说如果你修改一个 const 限定的对象,它是未定义的:

(C11 草案,6.7.3,6 个类型限定符)

If an attempt is made to modify an object defined with a const-qualified type through use of an lvalue with non-const-qualified type, the behavior is undefined.

如果代码调用未定义的行为,则 C 标准不需要诊断。一般来说,如果您的代码导致 UB 并且编译器可能无法在所有原因中帮助您,您就只能靠自己了。

关于更改 const 对象 - 没有警告?另外,在什么情况下是 UB?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32134305/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com