RError.com

RError.com Logo RError.com Logo

RError.com Navigation

  • 主页

Mobile menu

Close
  • 主页
  • 系统&网络
    • 热门问题
    • 最新问题
    • 标签
  • Ubuntu
    • 热门问题
    • 最新问题
    • 标签
  • 帮助
主页 / 问题 / 883387
Accepted
user294535
user294535
Asked:2020-09-20 15:11:01 +0000 UTC2020-09-20 15:11:01 +0000 UTC 2020-09-20 15:11:01 +0000 UTC

C语言,UB改变const时

  • 772
  1. 告诉我,标准真的说绕过const对象是未定义的行为吗?我试图自己找到这些信息,但没有成功。

  2. 如果情况确实如此(我几乎可以肯定),那么我不太明白这条规则在什么情况下适用。

    例如,即使在这样一个简单的例子中,也不是一切都是显而易见的:

    const int a = 1;
    int *b = (int*)&a;// Это уже UB или еще нет?
    *b = 2;// Это точно UB?
    

    我无法对此做出任何假设:

    const int *a = malloc(sizeof(int));
    int *b = (int*)a;// UB?
    *b = 1;// UB?
    

    这也不清楚:

    int i = 1;
    const int *a = &i;
    // Может, на следующей строке компилятор посчитает, что объект,
    // на который указывает "a", является константным?
    int *b = (int*)a;
    *a = 2;// И эта операция приведет к UB?
    

    和这个:

    // Абсолютно необходимая функция...
    void f(void *const _p)
    {
        void **p = (void**)&_p;
        *p = NULL;
    }
    
  3. 我经常在公司的代码指南中遇到const尽可能使用它的要求。例如,有一个函数将指向数据的指针放入链表中。由于该函数不会更改数据或指向数据的指针以及指向容器本身的指针,因此该函数通常如下所示:

    int list_push_front(list *const _list,
                        const void *const _data)
    {
        // ...
    
        // И приходится делать так...
        new_node->data = (void*)_data;
    
        // ...
    }
    

    但我们只是想说,该函数不会更改插入到列表中的数据,也不会更改输入指针参数,从而保护项目免受某些类型的ninja bug的影响。

    有可能这样做吗?那真的是礼貌吗,还是接下来的演员(void*)是UB?

c
  • 1 1 个回答
  • 10 Views

1 个回答

  • Voted
  1. Best Answer
    αλεχολυτ
    2020-09-20T16:08:01Z2020-09-20T16:08:01Z

    标准 C11 6.7.3/6:

    如果尝试通过使用具有非 const 限定类型的左值来修改使用 const 限定类型定义的对象,则行为未定义。


    int *b = &a;// Это уже UB или еще нет?
    

    目前还没有修改,只是分配了不兼容的指针类型。这是违反约束的,但还不是 UB。

    标准中有一个类似的例子(6.5.16.1/6):

    const char **cpp;
    char *p;
    const char c = 'A';
    cpp = &p; //constraint violation
    *cpp = &c; //valid
    *p = 0; //valid
    

    第一个赋值是不安全的,因为它允许以下有效代码尝试更改 const 对象 c 的值

    分配被认为是不安全的,因为 允许你改变常数值(上面说这是UB),但是转换本身并没有给出UB。

    更详细一点:

    cpp = &p; // сохраняем в cpp адрес указателя p
    *cpp = &c; // записываем в p адрес константы c 
    *p = 0; // попытка обнулить константу c (UB)
    

    如果您打印这些值*p并在此代码之后c,您可以看到例如以下内容:

    • 海湾合作委员会:0 0
    • 铛 0 65

    未定义行为的典型结果。在第一种情况下,常数设置为零,在第二种情况下,本质上相同的数据具有不同的值。


    const int *a = malloc(sizeof(int));
    

    右边的表达式不是一个常数,即 如果这里没有左边,分配的内存malloc是可以修改的,也就是说它的间接改变不是一个常量对象的改变,即 可接受的。这是我的反思,您需要更详细地查看标准。


    您问题第 3 点的转换与第 1 点的情况基本相同。我们只是将指针转换为存储。将来,如果原始数据是可变的(未声明为const),则可以使用新指针更改此数据,否则我们得到UB。

    顺便说一句,所有 UB 的列表在第J.2 节未定义的标准行为中给出。

    • 8

相关问题

Sidebar

Stats

  • 问题 10021
  • Answers 30001
  • 最佳答案 8000
  • 用户 6900
  • 常问
  • 回答
  • Marko Smith

    是否可以在 C++ 中继承类 <---> 结构?

    • 2 个回答
  • Marko Smith

    这种神经网络架构适合文本分类吗?

    • 1 个回答
  • Marko Smith

    为什么分配的工作方式不同?

    • 3 个回答
  • Marko Smith

    控制台中的光标坐标

    • 1 个回答
  • Marko Smith

    如何在 C++ 中删除类的实例?

    • 4 个回答
  • Marko Smith

    点是否属于线段的问题

    • 2 个回答
  • Marko Smith

    json结构错误

    • 1 个回答
  • Marko Smith

    ServiceWorker 中的“获取”事件

    • 1 个回答
  • Marko Smith

    c ++控制台应用程序exe文件[重复]

    • 1 个回答
  • Marko Smith

    按多列从sql表中选择

    • 1 个回答
  • Martin Hope
    Alexandr_TT 圣诞树动画 2020-12-23 00:38:08 +0000 UTC
  • Martin Hope
    Suvitruf - Andrei Apanasik 什么是空? 2020-08-21 01:48:09 +0000 UTC
  • Martin Hope
    Air 究竟是什么标识了网站访问者? 2020-11-03 15:49:20 +0000 UTC
  • Martin Hope
    Qwertiy 号码显示 9223372036854775807 2020-07-11 18:16:49 +0000 UTC
  • Martin Hope
    user216109 如何为黑客设下陷阱,或充分击退攻击? 2020-05-10 02:22:52 +0000 UTC
  • Martin Hope
    Qwertiy 并变成3个无穷大 2020-11-06 07:15:57 +0000 UTC
  • Martin Hope
    koks_rs 什么是样板代码? 2020-10-27 15:43:19 +0000 UTC
  • Martin Hope
    Sirop4ik 向 git 提交发布的正确方法是什么? 2020-10-05 00:02:00 +0000 UTC
  • Martin Hope
    faoxis 为什么在这么多示例中函数都称为 foo? 2020-08-15 04:42:49 +0000 UTC
  • Martin Hope
    Pavel Mayorov 如何从事件或回调函数中返回值?或者至少等他们完成。 2020-08-11 16:49:28 +0000 UTC

热门标签

javascript python java php c# c++ html android jquery mysql

Explore

  • 主页
  • 问题
    • 热门问题
    • 最新问题
  • 标签
  • 帮助

Footer

RError.com

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

帮助

© 2023 RError.com All Rights Reserve   沪ICP备12040472号-5