Function call with pointer to non-const and pointer to const arguments of same address(使用指向非常数的指针和指向相同地址的常量参数的指针的函数调用)
问题描述
我要编写一个函数,该函数使用指针输入一个数据数组并输出另一个数据数组。
我想知道,如果src
和dst
都指向同一个地址,结果会是什么,因为我知道编译器可以针对const进行优化。它是不是未定义的行为?(我标记了C和C++,因为我不确定它们之间的答案是否会不同,我想知道两者的情况。)
void f(const char *src, char *dst) {
dst[2] = src[0];
dst[1] = src[1];
dst[0] = src[2];
}
int main() {
char s[] = "123";
f(s,s);
printf("%s
", s);
return 0;
}
除了上面的问题,如果我删除原始代码中的const
,这个定义是否明确?
推荐答案
虽然行为确实定义良好-但编译器可以在您所指的意义上针对常量进行优化,这并不是。
也就是说,不允许假设只因为一个参数是const T* ptr
,ptr
指向的内存不会通过另一个指针更改。指针甚至不一定要相等。const
是一种义务,而不是保证-您(=函数)不通过指针进行更改义务。
restrict
关键字标记指针。因此,如果您编译这两个函数:
int foo(const int* x, int* y) {
int result = *x;
(*y)++;
return result + *x;
}
int bar(const int* x, int* restrict y) {
int result = *x;
(*y)++;
return result + *x;
}
foo()
函数必须从x
读取两次,而bar()
只需读取一次:
foo:
mov eax, DWORD PTR [rdi]
add DWORD PTR [rsi], 1
add eax, DWORD PTR [rdi] # second read
ret
bar:
mov eax, DWORD PTR [rdi]
add DWORD PTR [rsi], 1
add eax, eax # no second read
ret
观看直播GodBolt。
restrict
只是C中的一个关键字(从C99开始);不幸的是,到目前为止它还没有被引入到C++中(因为在C++中引入它更复杂)。然而,许多编译器确实有点支持它,例如__restrict
。
底线:编译器在编译f()
时必须支持您的深奥用例,并且不会有任何问题。
有关
restrict
的用例,请参阅this post。
这篇关于使用指向非常数的指针和指向相同地址的常量参数的指针的函数调用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:使用指向非常数的指针和指向相同地址的常量参数的指针的函数调用
基础教程推荐
- 调用std::Package_TASK::Get_Future()时可能出现争用情况 2022-12-17
- C++,'if' 表达式中的变量声明 2021-01-01
- 如何在 C++ 中处理或避免堆栈溢出 2022-01-01
- C++ 程序在执行 std::string 分配时总是崩溃 2022-01-01
- 设计字符串本地化的最佳方法 2022-01-01
- C++ 标准:取消引用 NULL 指针以获取引用? 2021-01-01
- 运算符重载的基本规则和习语是什么? 2022-10-31
- 如何定义双括号/双迭代器运算符,类似于向量的向量? 2022-01-01
- 什么是T&&(双与号)在 C++11 中是什么意思? 2022-11-04
- 您如何将 CreateThread 用于属于类成员的函数? 2021-01-01