1

Consider the following code:

struct A {
    int    n;
    double d;
};

int main() {
    auto a = A{.n = 1, .d = 3.14};
    
    // error: static_cast from 'int*' to 'A*' is not allowed
    auto _ = static_cast<A*>(&a.n); 
}

See https://godbolt.org/z/8814sEh79

However, the documentation of static_cast in cppref says: (emphasis mine)

Two objects a and b are pointer-interconvertible if:

  • they are the same object, or
  • one is a union object and the other is a non-static data member of that object, or
  • one is a standard-layout class object and the other is the first non-static data member of that object or any base class subobject of that object, or
  • there exists an object c such that a and c are pointer-interconvertible, and c and b are pointer-interconvertible.

According to the citation above, &a and &a.n should be pointer-interconvertible, so why is static_cast<A*>(&a.n) ill-formed?

4
  • 3
    pointer-interconvertible is irrelevant to static_cast. Note that the link "the C++ standard" references the cppreference site that is a wiki-like site and not the C++ standard. Commented Jul 10 at 5:03
  • The documentation entry I cited is under static_cast. Commented Jul 10 at 5:17
  • In the standard (if there is a conflict between content of the standard, and any other documentation - including cppreference - then the standard is correct, as that is a primary purpose of a standard), the text you quoted is not part of the section on static_cast Commented Jul 10 at 5:25
  • @Peter, Yes. What I cited is listed under static_cast, rather than reinterpret_cast. Commented Jul 10 at 5:43

2 Answers 2

4

Pointer-interconvertible is only mentioned in 7.g (in the since C++17 part) (emphasis mine):

  1. Otherwise, lvalue-to-rvalue, array-to-pointer, and function-to-pointer conversions are applied to expression. After these conversions, only the following conversions can be performed by static_cast:

[..]

g) An rvalue(until C++11)A prvalue(since C++11) of type “pointer to cv1 void” can be explicitly converted to the type “pointer to cv2 T”

[..]

  • If expression represents the address A of a byte in memory but A does not satisfy the alignment requirement of T, then the resulting pointer value is unspecified.
  • Otherwise, if expression points to an object a, and there is an object b of type T (ignoring cv-qualification) that is pointer-interconvertible (see below) with a, the result is a pointer to b.
  • Otherwise, the pointer value is unchanged by the conversion.

You don't use void* here, so pointer-interconvertible is irrelevant. No mistakes from cppreference.

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

Comments

2

What you are referring to is §6.8.4 [basic.compound], paragraph 4:

Two objects a and b are pointer-interconvertible if:

[...]

—(4.3) one is a standard-layout class object and the other is the first non-static data member of that object or

[...]

However, static_cast is not the tool for such a conversion, since for static_cast to work, the types need to be related. in your case, they are not. int is not related to A and vice versa. the only way you can achieve what you want is using a double static_cast over void* :

static_cast<int*>(static_cast<void*>(a));

which is equivalent to reinterpret_cast, which is the correct tool:

If two objects are pointer-interconvertible, then they have the same address, and it is possible to obtain a pointer to one from a pointer to the other via a reinterpret_cast (7.6.1.10)

3 Comments

However, what I cited is is listed under static_cast, rather than reinterpret_cast.
you can use static_cast, since void* is implicitly interconvertible to every other pointer. Hence you can use a double static_cast as I demonstrated.
@xmllmx yep and just under that statement they give an example of casting via void*. The statement says the pointers are equivalent, it doesn't say it's possible to directly static_cast between them

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.