改变const对象 - 没有警告?此外,在这种情况下,它是UB? [英] Changing const object - no warning? Also, in which case it is UB?
问题描述
为什么会出现在以下code无警告?
Why is there no warning in the following code?
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);
此外我有以下问题:是我做的未定义行为?
注:
Also I have following question: is what I did undefined behaviour? Note:
- 我觉得通过
学生
是很好,因为函数需要常量学生*
,我可以通过非常量
。对吗? - 但是,当我修改
的fscanf
该对象,并触发我UB?或者,这取决于学生
是否被声明为const还是不摆在首位(即功能之外)?
- I think passing
students
is fine because function expectsconst Student*
and I can pass nonconst
. Right? - But when I modify that object in
fscanf
, did I trigger UB? Or it depends whetherstudents
was declared const or not in the first place(outside that function)?
推荐答案
有在你的code无未定义的行为。
There's no undefined behaviour in your code.
通过来电者是一个什么可变对象。因此,它的优良直接修改或明确的转换:
What the caller passed is a mutable object. So it's fine to modify it either directly or by explicit cast:
int func(const int *p) {
int *q = (int*)p;
*q = 5;
}
是好的(可能是不明智的方式,但法律),只要FUNC传递给对象()
是一个可变的。
但是,如果传递的对象是常量
合格的话它会被不确定的行为。所以你的情况,它的不的定义。
But if the object passed was const
qualified then it would have been undefined behaviour. So in your case, it's not undefined.
限定符常量
仅在该函数不应该修改合约 DEST
。它有一个对象的实际的可变性无关。因此,修改常量限定调用UB与否要看对象是否传递到有任何这样的限定词。
The qualifier const
is only a contract that the function is not supposed to modify dest
. It has no bearing on the actual mutability of an object. So the modifying a const-qualified invokes UB or not depends whether the object passed to has any such qualifier.
至于警告,海湾合作委员会(5.1.1)警告为:
As for the warning, GCC (5.1.1) warns for:
int func(const int *p) {
fscanf(stdin, "%d", p);
}
与
warning: writing into constant object (argument 3) [-Wformat=]
大概VS不承认的fscanf()
修改对象。但C标准只是说,如果修改一个const限定对象是不确定的:
Probably VS doesn't recognize that fscanf()
modifies the object. But the C standard only says that it's undefined if you modify a const-qualified object:
的(C11草案6.7.3,6型预选赛)的
如果试图修改与一个定义的对象
通过使用一个左的非const限定的const限定型
类型,行为是不确定的。
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.
有没有诊断如果code调用不确定的行为由C标准要求。一般情况下,你是你自己,如果你的code使UB和编译器可能无法帮助你在所有的原因。
There's no diagnostic required by the C standard if the code invokes undefined behaviour. In general, you are on your own if your code causes UB and a compiler may not be able to help you in all causes.
这篇关于改变const对象 - 没有警告?此外,在这种情况下,它是UB?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!