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

2024-04-03

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

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(使用前将#替换为@)

更改 const 对象 - 没有警告?另外,什么情况下是UB? 的相关文章

随机推荐