The result of some pointer casts are described as unspecified. For example, [expr.static.cast]/13:
A prvalue of type “pointer to cv1 void” can be converted to a prvalue of type “pointer to cv2 T,” [...] If the original pointer value represents the address A of a byte in memory and A satisfies the alignment requirement of T, then the resulting pointer value represents the same address as the original pointer value, that is, A. The result of any other such pointer conversion is unspecified.
My question is: in the case where alignment is not satisfied, what are the possible results?
For example, are the following results permitted?
T
)T
in a completely separate part of memoryCode sample for reference:
#include <iostream>
int main(int argc, char **argv)
{
int *b = (int *)"Hello, world"; // (1)
*b = -1; // (2)
std::cout << argc << '\n';
}
Line (1)
triggers my above quote from [expr.static.cast]/13 because it is a reinterpret_cast
which is covered by [expr.reinterpret.cast]/7 which defines the conversion in terms of static_cast
ing through void *
.
If the unspecified result may be an invalid pointer value, then line (1)
may cause a hardware trap. (Reference: N4430 which clarifies similar wording that was in C++14 and C++11).
Corollary question: is there any case in which line 1
would cause undefined behaviour? (I don't think so at this stage; since C++14 invalid pointer value reading is implementation-defined or causes a hardware trap).
Also interesting is that line (2)
would in most cases be undefined behaviour due to strict aliasing violation (and perhaps other reasons too), however if the unspecified result may be &argc
then this program could output -1
without triggering undefined behaviour!
My question is: in the case where alignment is not satisfied, what are the possible results?
As far as I can tell N4303: Pointer safety and placement new partially answers this question, although somewhat indirectly. This paper refers to CWG issue 1412: Problems in specifying pointer conversions which brought about the changes to [expr.static.cast]/13 that you reference, specifically adding:
[...]If the original pointer value represents the address A of a byte in memory and A satisfies the alignment requirement of T, then the resulting pointer value represents the same address as the original pointer value, that is, A. The result of any other such pointer conversion is unspecified.[...]
In reference to this change N4303
says (emphasis mine):
Prior to the adoption of the resolution for DR 1412 [CWG1412], the value of bp is unspecified at the point of its initialization and its subsequent passing to operator new via the new-expression. Said pointer may be null, insufficiently aligned or otherwise dangerous to use.
So an unspecified conversion can results in:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With