C++ Weekly - Episode 129 脱水版: The One Feature Would Remove From C++
想从 C++ 中移除的一个特性
数组可以被赋值给一个指针, 并且没有任何警告.
const int array[] = {1, 2, 3, 4, 5};
const int *ptr = array;
数组到指针的隐式转换非常常见. 但是存在更糟糕的情况. 比如:
const int array[] = {1, 2, 3, 4, 5};
const int array2[] = {1, 2, 3, 4, 5};
return array == array2;
这种情况, 编译器将始终给出 false 值, 因为这比较的是两个数组的地址值, 而不是数组数值.
通过类型推导看看这个变量具体的类型, 也说明这是一个指针而不是数组.
const int array[] = {1, 2, 3, 4, 5};
const auto copy = array;
std::cout << std::is_pointer_v<decltype(copy)>; // return true
std::cout << std::is_array_v<decltype(copy)>; // return false
继续, 假如我们想从一个函数内返回一个数组:
auto get_array()
{
const int arrar[] = {1, 2, 3, 4, 5};
return array;
}
编译器将给出警告, 只是这返回了一个栈上地址. 这是非常危险的.
warning: address of stack memory associated with local variable 'arrar' returned [-Wreturn-stack-address]
同理, 假如如果我们想将数组作为函数参数:
void use_array(const int array[5]) { }
const int array[] = {1, 2, 3};
use_array(array);
我们以为函数接收的是一个包含五个整型的数组, 但是实际上它接收的还是一个指针, 甚至和数组尺寸毫无关系.
这种隐式的转换, 没有任何好处, 只会造成意想不到的后果. 甚至编译器无法给出任何警告或者错误. 这是作者最想中 C++ 中移除的一个特性.