最近,我无意中比较了Rust和C语言,它们使用了以下代码:

bool f(int* a, const int* b) {
  *a = 2;
  int ret = *b;
  *a = 3;
  return ret != 0;
}

在Rust(相同的代码,但使用Rust语法)中,它生成以下汇编代码:

    cmp      dword ptr [rsi], 0 
    mov      dword ptr [rdi], 3 
    setne al                    
    ret

使用gcc时,它会产生以下结果:

   mov      DWORD PTR [rdi], 2   
   mov      eax, DWORD PTR [rsi]
   mov      DWORD PTR [rdi], 3        
   test     eax, eax                  
   setne al                           
   ret

文本声称C函数不能优化第一行,因为ab可能指向同一个数字.在Rust中,这是不允许的,因此编译器可以对其进行优化.

现在我的问题是:

该函数的取值为const int*,即a pointer to a const int.我读到this question,它指出用指针修改const int会导致编译器警告,并导致最糟糕的UB类型转换.

如果我用两个指向同一整数的指针调用此函数,会不会产生UB?

为什么C编译器不能在假设两个指向同一个变量的指针是非法的/UB的情况下优化第一行呢?

Link to godbolt

推荐答案

函数int f(int *a, const int *b);promise 不会更改b through that pointer的内容...它没有promise 通过a指针访问变量.

如果ab指向同一个对象,那么更改through 100是合法的(当然,前提是基础对象是可修改的).

示例:

int val = 0;
f(&val, &val);

C++相关问答推荐

DPDK-DumpCap不捕获端口上的传入数据包

为什么GCC可以调用未定义的函数?

如何将字符串argv[]赋给C中的整型数组?

使用GOTO从多个嵌套循环C继续

为什么内核使用扩展到前后相同的宏定义?

如何在C宏中确定 struct 中元素的类型?

Make Node函数.S有什么问题吗?

判断X宏的空性

MacOS下C++的无阻塞键盘阅读

在C中创建任意类型的只读指针参数

试图创建一个基本的Word克隆,但遇到了障碍

如何将两个uint32_t值交织成一个uint64_t?

具有正确标头的C struct 定义问题

表达式x&;&;(~x)应该返回1还是0?它依赖于编译器吗?

向左移位3如何得到以字节为单位的位数?

将指针的地址加载到寄存器内联拇指组件中

为什么 int32_t 和 int16_t 在 printf 输出中具有相同的位数?

C23 中的 [[reproducible]] 和 [[unsequenced]] 属性是什么?什么时候应该使用它们?

inline 关键字导致 Clion 中的链接器错误

2 个经过restrict修饰的指针可以比较相等吗?