How does unspecified pointer conversion behave in C ++ 14?

The result of some pointer pointers is described as unspecified. For example, [expr.static.cast] / 13:

A value of type "pointer to cv1 void" can be converted to a prvalue of type "pointer to cv2 T", [...] If the initial value of the pointer represents the address A of the byte in memory and A satisfies the alignment requirement T, then the resulting value of the pointer is that the same address as the original pointer value, that is A. The result of any other such pointer conversion is not specified .

My question is: in the case when the alignment fails, what are the possible results?

For example, the following results are acceptable?

  • null pointer
  • invalid pointer value (i.e. a pointer that does not point to a dedicated storage of size T )
  • valid pointer to T in a completely separate piece of memory

Sample code 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) calls my quote from [expr.static.cast] / 13 above because it is reinterpret_cast , which is covered by [expr.reinterpret.cast] / 7, which defines the conversion in terms of static_cast via void * .

If the vague result may be an invalid pointer value, then line (1) may cause a hardware trap. (Ref: N4430 , which clarifies the similar wording that was in C ++ 14 and C ++ 11).

Corollary question: is there a case where line 1 causes undefined behavior? (I do not think that at this stage, since C ++ 14, an invalid reading of a pointer value is determined by the implementation or causes a hardware trap).


It is also interesting that line (2) in most cases would be undefined behavior due to severe violation of aliases (and possibly other reasons), however, if the undefined result could be &argc , then this program could output -1 without triggering undefined behavior !

+6
source share
1 answer

My question is: in the case when the alignment fails, what are the possible results?

As far as I can tell N4303: security and placement of new pointers partially answers this question, albeit somewhat indirectly. This article relates to CWG issue 1412: Problems specifying pointer conversions that led to the changes in [expr.static.cast] / 13 that you are referencing, in particular by adding:

[...] If the initial value of the pointer represents the address of A byte in memory, and A satisfies the alignment requirement T, then the obtained value of the pointer represents the same address as the original value of the pointer, that is, A. The result of any other such pointer conversion is not specified . [...]

Regarding this change, N4303 says (emphasis added):

Prior to the adoption of the resolution for DR 1412 [CWG1412], the value of bp is not indicated at the point of its initialization and subsequent transition to the new operator through a new expression. The specified pointer may be null, misaligned, or otherwise dangerous to use.

Thus, an undefined conversion can lead to:

  • Null pointer
  • Inadequately aligned pointer
  • Hazardous pointer
+3
source

Source: https://habr.com/ru/post/988825/


All Articles