I've look in the C++ standard and, when listing list of compound stuff, it does not mention anything like "pointer to data member of an instantiated class". So the question is:

struct test{
     int a;
    double d;
     .....
    //more complicated stuff here to make it a NON-pod structure)
   ....
};

test t;
double * pd;
void main(){
  pd = &(t.d);   // IS THIS PERMITTED?
// then use pd as a normal pointer to double
}

I really don't see why it shouldn't be permitted after all each object has a defined location and each member as a defined location so the address of the data is well defined.
But with C++ things are almost never what seem logical or intuitive.
So can some of the knowledgeable person here tell me if it is ok, and if so direct me to some part of the C++ standard that say so (maybe ISO 5.2.5 actually means it is ok, but I am not sure) ?
In the stunning case it would not be permitted, would it be permitted if the struct was a plain vanilla POD structure (if not, I'll be totally astonished)

Recommended Answers

All 6 Replies

>So can some of the knowledgeable person here tell me if it is ok,
>and if so direct me to some part of the C++ standard that say so

It's okay. Section 5.3.1, paragraph 2.

>void main(){
You might also enjoy section 3.6.1, paragraph 2. The number of people I've known who write code in a freestanding environment and post questions to a forum such as Daniweb is currently holding at zero.

Yes its permitted. 1st of all why do you need to use it? Second, the syntax gets pretty tricky. Here is an example :

#include <iostream>
using namespace std;

struct Foo{
	int x;
	int y;
	void print(){ cout << "(" << x << "," << y << ")" << endl; }
	Foo() : x(0), y(0){}
};

//typedef to make syntax simpler
typedef int Foo::*FooMemberPointer;
typedef void (Foo::*FooFunctionPointer)(void);

int main(){
	FooMemberPointer posX = &Foo::x;
	FooFunctionPointer display = &Foo::print;

	Foo littleFoo = Foo();

	(littleFoo.*display)();
	littleFoo.*posX = 100;
	(littleFoo.*display)();
	

	return 0;
}

To Narue and FirstPerson, I am not asking about a qualified id (which I know for sure is ok) such as :

&test::d // which is what I believe 5.3.1 paragraph 2 quoted by Narue refers to

but instead about the following expression which the standard appears to say it is ok (as far I understand it) but am not 100% sure this is what it actually means:

&(t.d) // which is what I believe 5.2.5 paragraph 6 is talking about: "if E2 is a non-static data member...

To FirstPerson:
The solution to the problem you proposed (counting path from one corner of a rectangle to another) is: combin(2*s, s) = (2s)! / (s! (2*s - s) ! ) = (2s)!/(s! s!)
where s is the number of sides.
For a 20x20 grids: 40!/(20! * 20!)

>I am not asking about a qualified id
I know that, and if you were reading for comprehension, you wouldn't have been so quick to dismiss my answer.

>&test::d // which is what I believe 5.3.1 paragraph 2 quoted by Narue refers to
Dude, read the whole freaking paragraph. It even starts with the material that you're looking for:

The result of the unary & operator is a pointer to its operand. The operand shall be an lvalue or a qualified-id. In the first
case, if the type of the expression is “T,” the type of the result is “pointer to T.”

In your example, t.d is an expression resulting in an lvalue with a type of double, thus &t.d legally produces a result of pointer to double. Section 5.2.5 confirms that t.d is an lvalue.

If you want to get answers from the standard, you can't gloss over whole sentences.

Narue, my difficulty was more with "Section 5.2.5 confirms that t.d is an lvalue." which I was not sure of, since I am a newcomer to C++ and can't be 100% I understand the full terminology/legalese.
Ok, now I have a confirmation from an expert.
Thanks.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.