最近,我无意中比较了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++相关问答推荐

哪个首选包含第三个库S头文件?#INCLUDE;文件名或#INCLUDE<;文件名&>?

发送和接收的消息中的Unix域套接字不匹配

将不同类型的指针传递给函数(C)

共享内存未授予父进程权限

当 n 是我们从用户那里获得的整数时,创建 n 个 struct 参数

通过修改c中的合并排序对数组的偶数索引进行排序

使用复合文字数组初始化的指针数组

创建 makefile 来编译位于不同目录中的多个源文件

文件指针引起的C程序分段错误

Zig 中 C 的system函数的惯用替代方案

如何在 C 中转储变量的位?

为什么这段代码中 free() 会导致程序崩溃?

编程时什么时候使用原子操作?

如何在C语言中为表格添加样式,使标题只出现在表格顶部.

为什么OpenMP归约会出现错误信息未找到'avgs'的用户定义归约?

除以非常数整数时在压电蜂鸣器上播放奇怪的音符

从未命名管道读取进程或更新共享内存中的变量的问题 C, linux

C语言找奇怪的除零表达式不会报错

对指向未定义类型的指针进行类型转换不会产生编译器错误

在 C 中迭代链表时空判断行为不正确