Reputation: 933
Consider this snippet:
#include <iostream>
int main() {
int s[6] {0, 1, 2, 3, 4, 5};
for ( auto && i: s ) {
std::cout << " " << i << std::endl;
}
}
This compiles and runs happily both under g++ and clang++.
It is taken for granted in many posts(here and here, for example), but it is unclear to me how the compiler can correctly infer the size of the array in the for range
for a type without iterator.
Can anyone answer or add a link to the reference?
Upvotes: 4
Views: 205
Reputation: 50550
According to the working draft [6.5.4/1]:
The range-based for statement
for ( for-range-declaration : for-range-initializer ) statement
is equivalent to
{ auto &&__range = for-range-initializer ; auto __begin = begin-expr ; auto __end = end-expr ; for ( ; __begin != __end; ++__begin ) { for-range-declaration = *__begin; statement } }
where
[...]
begin-expr and end-expr are determined as follows:
- if the for-range-initializer is an expression of array type R, begin-expr and end-expr are __range and __range + __bound, respectively, where __bound is the array bound. If R is an array of unknown size or an array of incomplete type, the program is ill-formed;
[...]
So it works mostly as @VladFromMoscow has already mentioned in his answer.
Upvotes: 5
Reputation: 311038
When the compiler compiles this statement
for ( auto && i: s ) {
std::cout << " " << i << std::endl;
it knows the type of the variable s
that is int[6]
.
So for arrays the compiler uses expressions like s
and s + 6
to define the range.
Upvotes: 4