9 c visual-studio language-lawyer
为什么以下代码中没有警告?
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;
}
Run Code Online (Sandbox Code Playgroud)
这就是我所说的:
Student students[5];
deserialize_students(students,5);
Run Code Online (Sandbox Code Playgroud)
另外我有以下问题:我做了什么未定义的行为?注意:
students很好,因为功能期望const Student*我可以通过非const.对?fscanf,我是否触发了UB?或者它取决于是否students首先声明了const(在该函数之外)?您的代码中没有未定义的行为。
调用者传递的是一个可变对象。因此可以直接修改它或通过显式强制转换来修改它:
int func(const int *p) {
int *q = (int*)p;
*q = 5;
}
Run Code Online (Sandbox Code Playgroud)
只要传递给的对象func()是可变的,就可以(可能是不明智的方式,但合法)。
但如果传递的对象是const合格的,那么它将是未定义的行为。所以就你而言,它不是未定义的。
限定符const只是函数不应修改的契约dest。它与对象的实际可变性无关。因此,修改 const 限定符是否会调用 UB 取决于传递给的对象是否具有此类限定符。
至于警告,GCC (5.1.1) 警告:
int func(const int *p) {
fscanf(stdin, "%d", p);
}
Run Code Online (Sandbox Code Playgroud)
和:
warning: writing into constant object (argument 3) [-Wformat=]
Run Code Online (Sandbox Code Playgroud)
VS 可能无法识别fscanf()修改对象。但 C 标准仅规定,如果修改 const 限定对象,则它是未定义的:
(C11草案,6.7.3,6种类型预选赛)
如果尝试通过使用非 const 限定类型的左值来修改使用 const 限定类型定义的对象,则行为未定义。
如果代码调用未定义的行为,则 C 标准不需要进行诊断。一般来说,如果您的代码导致 UB,您就得靠自己了,编译器可能无法在所有原因上为您提供帮助。
| 归档时间: |
|
| 查看次数: |
153 次 |
| 最近记录: |