for范围循环如何推断普通数组的大小?



考虑以下代码片段:

#include <iostream>
int main() {
  int s[6] {0, 1, 2, 3, 4, 5};
  for ( auto && i: s ) {
    std::cout << " " << i << std::endl;
  }
}

这在g++和clang++下都能很好地编译和运行。
这在许多帖子中被认为是理所当然的(例如,在这里和在这里),但我不清楚编译器如何能够正确地推断出for range中没有迭代器类型的数组大小。
谁能回答或添加一个链接到参考?

根据工作草案[6.5.4/1]:

基于范围的for语句
for ( for-range-declaration : for-range-initializer ) statement

等价于

{
  auto &&__range = for-range-initializer ;
  auto __begin = begin-expr ;
  auto __end = end-expr ;
  for ( ; __begin != __end; ++__begin ) {
      for-range-declaration = *__begin;
      statement
  }
}

,

[…]

begin-expr和end-expr的定义如下:

  • 如果for-range初始化式是数组类型R的表达式,begin-expr和end-expr分别是__range和__range + __bound,其中__bound是数组的边界。如果R是未知大小的数组或不完整类型的数组,则程序是病态的;

[…]

所以它主要是像@VladFromMoscow在他的回答中已经提到的那样。

当编译器编译此语句时

  for ( auto && i: s ) {
    std::cout << " " << i << std::endl;

它知道变量sint[6]的类型

对于数组,编译器使用像ss + 6这样的表达式来定义范围。

最新更新