Reputation: 7367
Consider the following simple example computing lenght of an array:
#include <iostream>
int a[] = {1, 2, 4};
int main(){ std::cout << sizeof(a)/sizeof(a[0]) << std::endl; }
The Standard N4296::8.3.4/7 [dcl.array]
If E is an n-dimensional array of rank i×j×. . .×k, then E appearing in an expression that is subject to the array-to-pointer conversion (4.2) is converted to a pointer to an (n−1)-dimensional array with rank j ×. . .×k.
N4296::4.2/1 [conv.array]
An lvalue or rvalue of type “array of N T” or “array of unknown bound of T” can be converted to a prvalue of type “pointer to T”. The result is a pointer to the first element of the array.
So what is the expressions which are the subject of the convertion? Looks like unevaluated operands are not the subject.
http://coliru.stacked-crooked.com/a/36a1d02c7feff41c
Upvotes: 0
Views: 231
Reputation: 119467
I don't know if anyone can name all the rules off the top of their head, so a community wiki may be appropriate.
The array to pointer conversion occurs in the following contexts. All references are to the C++11 standard.
+
operator ([expr.unary.op]/7)+
operator ([expr.add]/1)-
operator ([expr.add]/2)The array to pointer conversion does not occur in the following contexts:
&
operator ([expr.unary.op]/3)sizeof
([expr.sizeof]/4)1 This includes the case where an array of T
is passed to a function expecting cv T*
, cv void*
, or bool
, when a user-defined conversion requires one of those types, etc.
2 This includes contextual conversions to bool
as they occur in if
statements and the like.
Upvotes: 2
Reputation: 36617
The rule of thumb I work by is "in any part of an expression that produces a value result that can be stored in a pointer but cannot be stored in an array".
So, for example;
array + 0
converts array
to a pointer before doing the addition, and gives a result that is a pointer.f(array)
converts array
to a pointer before calling the function f()
that accepts a pointer or an array (not a reference).array[0]
is not required to convert array
to a pointer (but the
compiler is free to, since it makes no difference on the result of that expression).sizeof array
does not convert array
to a pointer (since it doesn't
evaluate array
at all, just its size)p = array
converts array
to a pointer and that value
is stored in p
I'm sure there are some cases I've missed, but that simple rule works reasonably well. Of course, it is based on an understanding of what an expression is.....
Upvotes: 1
Reputation: 206717
I know of the following expressions in which an array is not converted/decayed to a pointer.
sizeof
operator: sizeof(array)
&array
int (&ref)[3] = array;
.decltype
: decltype(array)
Upvotes: 3