Using std::launder to get a pointer to an active object member from a pointer to an inactive object?

前端 未结 1 332
暖寄归人
暖寄归人 2021-01-11 19:55

This question followes this one

Let\'s consider this example code:

struct sso
  {
  union{
    struct {
      char* ptr;
      char size         


        
1条回答
  •  囚心锁ツ
    2021-01-11 20:18

    Let's consider that the ABI is well specified and that we know that size_r[7] is at the same address as short_str[15]

    It depends entirely on what that guarantee means exactly.

    A compiler is free to guarantee that

    Sso.short_str[15]
    

    can be accessed and modified and everything even when Sso.large_str is currently active, and get exactly the semantics you expect.

    Or it is free not to give that guarantee.

    There is no restriction on the behavior or programs that are ill-formed or exhibit undefined behavior.

    As there is no object there, &Sso.short_str[15] isn't pointer-interconvertible with anything. An object that isn't there doesn't have the "same address" as another object.

    Launder is defined in terms of a pointer to a pre-existing object. That pointer is then destroyed, and a new object with the same address is created (which is well defined). std::launder then lets you take the pointer to the object that no longer exists and get a pointer to the existing object.

    What you are doing is not that. If you took &short_str[15] when it was engaged, you'd have a pointer to an object. And the ABI could say that this was at the same address as size_r[7]. And now std::launder would be in the domain of validity.

    But the compiler could just go a step further and define that short_str[15] refers to the same object as size_r[7] even if it isn't active.

    The weakest ABI guarantee that I could see being consistent with your stuff would only work if you took the address of short_str[15] when it was active; later, you would engage the large_str, and then you could launder from &short_str[15] to &size_r[7]. The strongest ABI guarantee that is consistent with your statement makes the call to std::launder not required. Somewhere in the middle std::launder would be required.

    0 讨论(0)
提交回复
热议问题