使用-Warray-bounds
编译this code时。声明array2 array index 3 is past the end of the array (which contains 3 elements)
时收到警告。但是,在声明array1时,即使它必须是相同的类型,从而携带相同的大小信息,也并非如此。这是c中的错误吗?
enum class Format : int {
Off = 55,
FormatA = 66,
FormatB = 77,
};
inline Format (&AllFormats())[3] {
static Format values[] = {
Format::Off,
Format::FormatA,
Format::FormatB
};
return values;
}
int main()
{
auto array1 = AllFormats();
auto v3 = array1[3];
Format (&array2)[3] = AllFormats();
v3 = array2[3];
}
答案 0 :(得分:7)
即使它必须是相同的类型
您会认为。但是,如果您检查一下,就会发现它们实际上不是同一类型:
.updateProjectionMatrix()
std::cout << typeid(array1).name() << "\n";
std::cout << typeid(array2).name() << "\n";
糟糕。由P6Format
A3_6Format
返回的数组在分配给AllFormats
变量时会衰减为指针,因为这是auto
的类型推导规则的工作方式。比较:
auto
为防止这种情况,请将int& foo() {
static int x = 42;
return x;
}
auto x = foo(); // Type of `x` is `int`, not `int&`.
声明为array1
或auto&
。
答案 1 :(得分:4)
import { NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
import { Routes, RouterModule } from '@angular/router';
import { UserAlbumsComponent } from './user-albums.component';
const routes: Routes = [
{ path: '**', component: UserAlbumsComponent }
];
@NgModule({
imports: [
CommonModule,
RouterModule.forChild(routes)
],
declarations: [UserAlbumsComponent]
})
export class UserAlbumsModule { }
是一个指针。
使用array1
代替那里的auto&&
。
答案 2 :(得分:4)
但即使必须是相同的类型,也不会在第16行
假设它是指auto array1 = AllFormats()
,则它的类型不同。永远不会推论auto
为参考,因此array1
不是参考。它是一个非引用,并被推论为衰减的结果,即指向Format
的指针。
由于指针类型不包含有关指针数组大小的信息,因此编译器无法证明下标运算符会使数组溢出。
要声明引用,可以使用以下任一方法:
auto& array1 = AllFormats(); // 1.
auto&& array1 = AllFormats(); // 2.
decltype(auto) array1 = AllFormats(); // 3.
AllFormats
返回一个左值引用。如果AllFormats
返回Format&&
,它将是一个右值引用。auto
类型推导使用与decltype
推导不同的规则。一个主要区别是auto
决不是引用,而decltype(E);
可能是引用,具体取决于表达式E
。 decltype(auto) var = E
允许使用decltype
规则进行声明,就像使用decltype(E)
一样。答案 3 :(得分:2)
在
auto array1 = AllFormats();
auto v3 = array1[3];
array1
不是数组,因此无法检查范围。即使您通过引用返回,auto
也不会演绎一个,因此数组会衰减为一个指针,而array1
会推导为Format *
。
Format (&array2)[3] = AllFormats();
v3 = array2[3];
生成警告,因为array2
是对数组的引用,因此它知道大小。
要让auto
推导一个数组,您需要使用auto&
(仅在返回的是左值引用时有效),或使用auto&&
(将引用绑定到)任何东西。