0

NOTE: I'm not trying to solve a programming problem; I'm trying to learn.

Given this c++ code:

#include <iostream>

class class1
{
    public:
        int attr1 = 12;
        class1()
        {

        }   // breakpoint
};

int main()
{
    class1 c1;
}

Using VS2019; breakpoint set per above. In Immediate Window:

this
0x000000877f54fcf4 {attr1=0x0000000c }
    attr1: 0x0000000c

attr1
0x0000000c

class1::attr1
0x0000000c

&(class1::attr1)    (am able to use "class1" here, I assume, because it's clear I'm not referring to a typename)
0x000000877f54fcf4 {0x0000000c}

class1        (returns blank line?)


&class1       (treats class1 as type)
type name is not allowed

Also, in Memory window, entering "class1" in Address field shows: Unable to evaluate the expression.

At the breakpoint, my questions:

  1. How can I get the address of class1 in the immediate window by using the identifier "class1"? (yes, I know it's the same address as "this")
  2. Same question re: Memory window
  3. Why does "class1" in Immediate Window return blank?

enter image description here

SAbboushi
  • 59
  • 6
  • 1
    Types don't have addresses. You may be looking for the address of `c1` which is an instance of `class1`. – François Andrieux Sep 06 '20 at 17:19
  • You should use the object `c1` instead. Note that you also used `attr1` and not `int`. – Thomas Weller Sep 06 '20 at 17:19
  • class names do not exist at runtime. [They are not objects](https://en.cppreference.com/w/cpp/language/object). They have no size or address. – user4581301 Sep 06 '20 at 17:20
  • 1
    @user4581301 Classes do have a size though. – François Andrieux Sep 06 '20 at 17:20
  • OK. They have size, they do not require storage. – user4581301 Sep 06 '20 at 17:20
  • 2
    _(yes, I know it's the same address as "this")_ no, that's wrong. A class define a type, then you can create an instance of that type. You can get the addtress of the instance, but not of a type. imagine the following: `int x;` you can get the address for variable `x`, but not for the type `int` – Gian Paolo Sep 06 '20 at 17:21
  • @user4581301: how do you think "they have size" and "do not require storage" go together? That size must go somewhere, be it in the code section of the DLL – Thomas Weller Sep 06 '20 at 17:25
  • A class (a type) just describes a thing. It has no size or representation it's just a blueprint. You can create *instances* of a type and those have sizes since they are actual things that exist - something concrete created from the class blueprint. – Jesper Juhl Sep 06 '20 at 18:05
  • Thanks for responses but I'm still left with the same question: if I can get the value of "attr1" from "class1::attr1" and the address of attr1 from "&(class1::attr1)", then why can't I get the address of "class1"? – SAbboushi Sep 06 '20 at 19:01
  • It seems to me that "class1" in "class1::attr1" is not being treated as a type... correct? – SAbboushi Sep 06 '20 at 19:20
  • @GianPaolo: re: your point about `int`: Immediate Window" "int" returns "type name is not allowed" But as I pointed out in my question #3, "class1" return a blank line. So this confuses me... – SAbboushi Sep 06 '20 at 19:36
  • @SAbboushi `&(class1::attr1)` is a member pointer, which is distinct from a normal object pointer. It does not point to an actual object. It needs to be paired with a `class1*` pointer. Together it yields a pointer to the `attr1` member of the instance the `class*` pointer points to. In other words `&(class1::attr1)` is a pointer of sorts but not an object pointer and does not point to an address. Most likely it is represented as a memory offset. – François Andrieux Sep 06 '20 at 19:48
  • >> and does not point to an address >> It does not point to an actual object @FrançoisAndrieux: if you look at my original post, you'll see that an address is returned. Examining this address in a memory window shows the value of attr1 at that address. The address is also the same as address returned by "this" (an actual object) which I think makes sense since attr1 is the first/only member. This address is the same address as c1 object address (after execution returns to main()). So it's still unclear to me what I am missing/misunderstanding... – SAbboushi Sep 06 '20 at 19:58
  • @SAbboushi It isn't clear to me how you got that result. Maybe you used your debugging tools while your code was stopped within the context of a member function, and it assumed `this` as the associated object. But I can assure you that a pointer to member like `&(class1::attr1)` does not point to an object. – François Andrieux Sep 06 '20 at 20:04
  • Thanks - if you look at the original post, you'll see where the breakpoint is/code was stopped. – SAbboushi Sep 06 '20 at 20:12
  • @SAbboushi I'm not familiar with VS2019's debugger. Because a member pointer on its own the debugger probably assumes that you meant to use `this` with it. Try in `int main` and see if it changes. – François Andrieux Sep 06 '20 at 20:15
  • After returning to `int main`, Immediate Window for "&(class1::attr1)" returns "a nonstatic member reference must be relative to a specific object" To recap the questions/responses that to me are unresolved: It seems that "class1" during the constructor is treated both as a type as evidenced by ``` &class1 (treats class1 as type) type name is not allowed ``` and as a class as evidenced by ``` &(class1::attr1) 0x000000877f54fcf4 {0x0000000c} ``` where the address of object is returned as confirmed by "&c1" after object has been initialized. – SAbboushi Sep 06 '20 at 20:52
  • if I can get the value of "attr1" from "class1::attr1" and the address of attr1 from "&(class1::attr1)", then why can't I get the address of "class1"? Is there a way for me to qualify "class1" in debugger so that it treats it in the same way as it does in "&(class1::attr1)"? And also, any explanation as to why "class1" value is returned as a blank line? – SAbboushi Sep 06 '20 at 20:55

1 Answers1

0

I am guessing that you wish to access the RTTI of the class. Chances are, different compilers may implement it slightly differently to one another.

That said, there is an operator called typeid: https://en.cppreference.com/w/cpp/language/typeid

Take a look at this blog for an example of using it with the Visual-C compiler: https://blog.quarkslab.com/visual-c-rtti-inspection.html

which features this example:

#include <iostream>
class MyClass {};
class MyDerivedClass : public MyClass {};

template<typename T> void PrintTypeInformation(char const* pVarName, T const& t)
{
  std::cout
    << pVarName
    << ": type: "     << typeid(t).name()
    << ", raw type: " << typeid(t).raw_name()
    << std::endl;
}

int main(void)
{
  MyClass cls;
  MyDerivedClass *drv;
  int n;
  char c;
  __int64 l;
  double d;

#define PRINT_TYPE_INFORMATION(var) PrintTypeInformation(#var, var)

  PRINT_TYPE_INFORMATION(cls);
  PRINT_TYPE_INFORMATION(drv);
  PRINT_TYPE_INFORMATION(n);
  PRINT_TYPE_INFORMATION(c);
  PRINT_TYPE_INFORMATION(&l);
  PRINT_TYPE_INFORMATION(d);

  return 0;
}

which outputs:

cls: type: class MyClass, raw type: .?AVMyClass@@
drv: type: class MyDerivedClass *, raw type: .PAVMyDerivedClass@@
n: type: int, raw type: .H
c: type: char, raw type: .D
&l: type: __int64 *, raw type: .PA_J
d: type: double, raw type: .N

If you're interested in accessing the debug information in the PDB file (MSVC) then take a look at the answers to this question: Do debugging information reveal code in C++ / MSVC?

Den-Jason
  • 2,395
  • 1
  • 22
  • 17
  • Thanks @Den-Jason. The info may give me clues on how to answer my question, but it's above my head... Again my thanks to all. It seems my question is highly implementation/debugger specific and the answer may be "when within class1 scope, VS debugger allows using class1 identifier for non-static member access of the object, but lacking an SRO, debugger treats class1 identifier as a type" – SAbboushi Sep 11 '20 at 15:10