2

[defns.dynamic.type] reads

⟨glvalue⟩ type of the most derived object to which the glvalue refers

from which I understand that given

struct B { virtual ~B() = default; };
struct D : B {};
std::unique_ptr<B const> d = std::make_unique<D const>();

D const is the dynamic type of *d, even if it happens to be known at compile time.

From [defns.static.type] I read that (my emphasis)

type of an expression resulting from analysis of the program without considering execution semantics

Does it mean that *d's static type is also D const, rather than B const?

After all the compiler can (and often does) carry on an analysis to conclude that *d is indeed a D const, not a B const.

4
  • Does that even compile? I didn't know that std::unique_ptr would automatically downcast like a dumb pointer does. Commented Nov 7, 2024 at 18:52
  • 1
    @MarkRansom It's an upcast, and yes, it's well capable of doing that. See constructor 6: en.cppreference.com/w/cpp/memory/unique_ptr/unique_ptr Commented Nov 7, 2024 at 18:59
  • @Yksisarvinen interesting, thanks for that. And sorry for my terminology sloppiness. Commented Nov 7, 2024 at 19:28
  • @MarkRansom, if unique_ptr was not usable like in my code snippet, it would basically useless, because you couln't use it to handle polymorphic type, which after all is the only real reason for using pointers instead of just values. Commented Nov 7, 2024 at 19:28

2 Answers 2

4

After the shown declaration

  • the static type of the expression *d is B const and its value category is glvalue;

  • the dynamic type of the object referenced by the glvalue expression *d is D const.

The compiler could figure out that the dynamic type is the derived class and could omit virtual dispatch. But that is knowledge resulting from analysis of the program by considering execution semantics, which is exactly the opposite of what the quote in the post says.

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

Comments

1

"Static type" just means the type of an expression. Various rules in the standard tell you how the type of an expression is determined. "Dynamic type" means the type of an object that an expression refers to.

The "static type" of *d is the type of the expression *d, which is const B. Period. (It's determined by the declaration of operator*.) The dynamic type of *d is the type of the object that *d refers to, so const D.

Comments

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.