为什么下面的代码没有警告呢?
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
. Right?
- 但是当我修改该对象时
fscanf
,我触发了UB吗?或者取决于是否students
是否首先声明为 const(在该函数之外)?
您的代码中没有未定义的行为。
调用者传递的是一个可变对象。因此可以直接修改它或通过显式强制转换来修改它:
int func(const int *p) {
int *q = (int*)p;
*q = 5;
}
没问题(可能是不明智的方式,但合法),只要对象传递给func()
是一个可变的。
但如果传递的对象是const
合格的话,这将是未定义的行为。所以在你的情况下,它是not不明确的。
预选赛const
只是一个函数不应该修改的合约dest
。它与actual对象的可变性。因此,修改 const 限定符是否会调用 UB 取决于传递给的对象是否具有此类限定符。
至于警告,GCC (5.1.1) 警告:
int func(const int *p) {
fscanf(stdin, "%d", p);
}
with:
warning: writing into constant object (argument 3) [-Wformat=]
可能VS不认识这个fscanf()
修改对象。但 C 标准仅规定,如果修改 const 限定对象,则它是未定义的:
(C11草案,6.7.3,6种类型预选赛)
如果尝试修改用 a 定义的对象
通过使用带有非 const 限定的左值来限定 const 限定类型
类型,行为未定义。
如果代码调用未定义的行为,则 C 标准不需要进行诊断。一般来说,如果您的代码导致 UB,您就得靠自己了,编译器可能无法在所有原因上为您提供帮助。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)