改变const对象 - 没有警告?此外,在这种情况下,它是UB? [英] Changing const object - no warning? Also, in which case it is UB?

查看:756
本文介绍了改变const对象 - 没有警告?此外,在这种情况下,它是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 expects const Student* and I can pass non const. Right?
  • But when I modify that object in fscanf, did I trigger UB? Or it depends whether students 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆