0

I have problem in this line std::cout << &X::a << std::endl; this line print 1 supposed to printed address of &X::a

this my code

#include <iostream>
#include <string>
#include <iomanip>

class X
{
public:
    int a;
    void f(int b);
};

void X::f(int b)
{
    std::cout << "the value of b is " << b << std::endl;
}

void add()
{
    std::cout << "Hello this function hello" << std::endl;
}
int main()
{
    void (*funcPtr)(void) = add;
    funcPtr();
    int X::*ptrnumber = &X::a;
    void (X::*ptrfunction)(int) = &X::f;
    X xobj;
    xobj.*ptrnumber = 10;
    std::cout << "the vslue of a is " << xobj.*ptrnumber << std::endl;
    (xobj.*ptrfunction)(20);
    std::cout << std::hex << &X::a << std::endl;
    //std::cout << funcPtr << std::endl;
}

i compiled with different complier c++ but i have same output
i displayed type of this "M1Xi" i don't know this data type

  • `&X::a` has no address. – tkausl Aug 05 '23 at 17:56
  • 2
    `X::a` doesn't have an address; `X` is a type, not an object. If you write `X x;` then `x.a` will have an address. – Pete Becker Aug 05 '23 at 17:56
  • 1
    `bool` overload is taken... – Jarod42 Aug 05 '23 at 18:01
  • 1
    I asked chatGpt on the reason tel me it that is &X::a is address – Hassan Lakhal Aug 05 '23 at 18:11
  • 7
    ChatGPT is just a dumb chatbot. It is not an experienced C++ developer, who actually knows and understands C++. – Sam Varshavchik Aug 05 '23 at 18:20
  • @Jarod42 -- I'm missing something. Yes, `&X::a` is a pointer-to-member. But `X::a` does not have an address; a pointer-to-member is not an address, despite having "pointer" in its name. So, why is your comment addressed to me? – Pete Becker Aug 05 '23 at 18:52
  • @HassanLakhal -- `&X::a` is a pointer-to-member-data, but don't be fooled by that word "pointer" in its name. It's not what we typically call a pointer. In particular, it doesn't point at any data. You can use it to point at data when you have an object of type `X`: `int X::* ptr = &X::a; X x; x.*ptr = 3;` uses `&X::a` to point at the `a` element of the object `x`. – Pete Becker Aug 05 '23 at 18:58
  • @PeteBecker sorry but &X::a is a pointer to member - https://stackoverflow.com/q/670734/3723423 – Christophe Aug 05 '23 at 19:15
  • @PeteBecker it has an address, but it is a relative address and is to be used with .* – Christophe Aug 05 '23 at 19:18
  • Does this answer your question? [Why function pointer address is printing in bool type in c++?](https://stackoverflow.com/questions/40487014/why-function-pointer-address-is-printing-in-bool-type-in-c) – Jan Schultke Aug 05 '23 at 19:27
  • @JanSchultke this seems very close. However, these are about members pointers to functions, and function pointers are sufficiently different from pointers to data to justify a more specific question. – Christophe Aug 05 '23 at 20:38
  • This question was closed due to lack of clarity. However, it has all the clarity needed. It deserves to be reopened. Let's prove here that experienced C++ developers give better insight than ChatGPT ;-) – Christophe Aug 05 '23 at 20:40
  • @Christophe — not sure what you’re sorry for; I’ve said several times that `&X::a` is a pointer-to-member[-data]. – Pete Becker Aug 05 '23 at 21:10
  • @Christophe — It isn’t necessarily a relative address (if by that you mean offset within the class data) because of virtual bases. A data member of a virtual base class does not have a fixed location in the derived class. Multiple inheritance moves things around even if you haven’t touched the original derived class. – Pete Becker Aug 05 '23 at 21:24
  • @PeteBecker I used the term relative in its general sense, i.e that it is only defined in relation with something else. I was not using it in the way assemblers use it (offset to a base). As you pointed out the offset compared to the address of the object is governed by complex rules, that are moreover implementation dependent. – Christophe Aug 05 '23 at 21:45
  • Close voters: what details do you think are lacking? It’s perfectly clear what the question is about; there are two answers that address the question. What more do you want? Could you at least provide a clue, so that the question could be improved? – Pete Becker Aug 06 '23 at 00:01

2 Answers2

3

&X::f and &X::a are not pointers. Because f and a are both non-static members, they are instead member pointers, which behave very differently from pointers regardless of the naming and syntax similarity.

A member pointer (whether function or data member) does not represent an address. So it doesn't make sense to try to print its address.

So there is also no overload for << with std::ostream in the standard library that would take a member pointer either.

However, there is an overload taking a bool as parameter and it is possible to implicitly convert a member pointer to bool. The result is false if the member pointer has the null member pointer value and true otherwise. With the default setting true is then printed as 1.

user17732522
  • 53,019
  • 2
  • 56
  • 105
  • i did't really get the sentence "A Pointer-to-member (whether function or data member) does not represent an address. So it doesn't make sense to try to print its address.", normally it means that this pointer holds the address of this data member? – Hassan Lakhal Aug 05 '23 at 19:55
  • @HassanLakhal No, a member pointer is not a pointer at all. It doesn't point to a concrete member subobject of an object. It does so only in combination with a pointer to the class object when applying the `.*` or `->*` operators. The member pointer itself only abstractly identifies one member of a given class type among other members (of the same type) in the same (or inheritance-related) class, not as a concrete object of the class type. – user17732522 Aug 05 '23 at 20:00
  • @HassanLakhal I would recommend you to read up about member pointers in an introduction to the language, such as one of the [recommended books](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). They have nothing to do with normal pointers and explaining what they are and how they are used wouldn't fit here. – user17732522 Aug 05 '23 at 20:03
1

The expression &X::a is not an address that you could use in an ordinary address. It is a relative address to a member. It can only be used with a pointer to member.

Pointer to members can be converted to other pointer to members and only with constraints. They cannot be converted to other kind of pointers or to int. It is difficult in this condition to print their value.

The only conversion possible is to a boolean, and it is meant to see if it is null or not. Because a pointer to member can be nullptr:

int X::*px = &X::a;
bool bx = px; std::cout << bx <<std::endl; 
px = nullptr; 
bool bn = px; std::cout << bn <<std::endl; 

If you want to print the address of the pointer to member, you must dereference it with an object:

std::cout << std::hex << &(xobj.*(&X::a)) << std::endl; 

As you may imagine, it is not possible to use tricks using dereferencing a nullptr to member or using a nullptr as object address, since dereferencing a null pointer is UB. By the way, this is not a real problem, because the standard makes very little guarantees about the layout of an object, so that this relative address is of little use on its own.

Christophe
  • 68,716
  • 7
  • 72
  • 138