3

I came across this code

float range[] = { 0, 256 };
const float* histRange = { range };

For me, { range } means 'array of arrays' since the variable range is an array of float. Therefore, for me, it would make more sense.

const float** histRange = { range };

But the compiler (VC++ from VS2019) doesn't like it (expects a const float*)

Could someone explain to me why {range} is not an 'array of arrays' (float**), but instead just a regular float pointer?

Interesting fact: When I do

float range[] = { 0, 256 };
auto aa = { range };
auto bb = range;
std::cout << typeid(aa).name() << std::endl;
std::cout << typeid(bb).name() << std::endl;

the output is (in VC++ VS2019)

std::initializer_list<float * __ptr64>
float * __ptr64
5
  • This doesn't work either: float* range = { 0, 256 }; and this will: const float* histRange[] = { range }; This is because { 0, 256 } and { range } are not arrays that you can point to, they are lists of values ready to initialize arrays. Pedantically, std::initializer_list<T> doesn't decay to a T* the same way that a real T[] does. Commented Dec 28, 2020 at 7:29
  • @BenVoigt That looks like an answer. Commented Dec 28, 2020 at 7:35
  • @cigien: I would expect a proper answer to cover how list-initialization can also be used to initialize a scalar by supplying the arguments expected by its constructor. Commented Dec 28, 2020 at 7:39
  • @BenVoigt Yes, that would make the answer better for sure. If you don't feel the comment is sufficient as an answer, that's reasonable. Commented Dec 28, 2020 at 7:41
  • @BenVoigt pedantically a braced list is not a std::initializer_list except in certain contexts, which this is not one of Commented Dec 28, 2020 at 7:47

1 Answer 1

4

Text enclosed by braces is not an expression, and doesn't have a type. A braced list is only allowed in certain contexts, and in each case the language definition specifies the semantics of the larger context featuring that braced list.

In the line:

const float* histRange = { range };

we are initializing a scalar, not an array. The [] syntax is required to declare an array. It is not defining an unnamed array and having histRange point to the first element of that array.

The meaning of a braced list as initializer for a scalar (other than auto) is that the list must contain 0 or 1 elements; and if it contains 1 element then the behaviour is the same as if the braces were omitted.

Or in other words, initializers for scalars can optionally have braces, e.g. int x = { 5 };. This rule has been around since C.

A braced list with more than one element would not be allowed in this context (although gcc accepts it with a warning by default, and ignores any list elements besides the first).

So, const float* histRange = range; is allowed because range is an array, and there is an implicit conversion from array to pointer-to-first-element-of-that-array, which has type float *, and there is also implicit conversion from float * to const float *.


const float** histRange = range; would be an error (with or without optional braces) because there is no conversion from float * to const float **.


Also allowed would be const float *histArr[1] = { range }; which is an array of pointers to const float and length 1; here you could have a braced list and a longer length.


In auto aa = { range }; , the use of auto has its own rules of type deduction, and the rule is that this syntax (without * or [] in the declarator) deduces aa as having type std::initializer_list<T> of one element.

Note that it would still not be correct to say that { range } has a type. The std::initializer_list<T> is initialized by the elements of the braced list.

This rule is slightly controversial; in C++11 auto aa{range}; was the same, but in C++17 it was changed to deduce aa to have the same type as range.

Sign up to request clarification or add additional context in comments.

1 Comment

thanks, this is a very clear explanation.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.