int* array = new int[len];
for[] (int i : array) {}
There are several points which must be addressed; I'll tackle them one at a time.
Does the run-time knows the size of the array?
In certain conditions, it must. As you pointed out, a call to delete[]
will call the destructor of each element (in reserve order) and therefore must know how many there are.
However, by not specifying that the number of elements must be known, and accessible, the C++ standard allows an implementation to omit it whenever the call to the destructor is not required (std::is_trivially_destructible<T>::value
evaluates to true
).
Can the run-time distinguish between pointer and array?
In general, no.
When you have a pointer, it could point to anything:
- a single item, or an item in an array,
- the first item in an array, or any other,
- an array on the stack, or an array on the heap,
- just an array, or an array part of a larger object.
This is the reason what delete[]
exists, and using delete
here would be incorrect. With delete[]
, you the user state: this pointer points to the first item of a heap-allocated array.
The implementation can then assume that, for example, in the 8 bytes preceding this first item it can find the size of the array. Without you guaranteeing this, those 8 bytes could be anything.
Then, why not go all the way and create for[] (int i : array)
?
There are two reasons:
- As mentioned, today an implementation can elide the size on a number of elements; with this new
for[]
syntax, it would no longer be possible on a per-type basis.
- It's not worth it.
Let us be honest, new[]
and delete[]
are relics of an older time. They are incredibly awkward:
- the number of elements has to be known in advance, and cannot be changed,
- the elements must be default constructible, or otherwise C-ish,
and unsafe to use:
- the number of elements is inaccessible to the user.
There is generally no reason to use new[]
and delete[]
in modern C++. Most of the times a std::vector
should be preferred; in the few instances where the capacity is superfluous, a std::dynarray
is still better (because it keeps track of the size).
Therefore, without a valid reason to keep using these statements, there is no motivation to include new semantic constructs specifically dedicated to handling them.
And should anyone be motivated enough to make such a proposal:
- the inhibition of the current optimization, a violation of C++ philosophy of "You don't pay for what you don't use", would likely be held against them,
- the inclusion of new syntax, when modern C++ proposals have gone to great lengths to avoid it as much as possible (to the point of having a library defined
std::variant
), would also likely be held against them.
I recommend that you simply use std::vector
.