Topic: Pointer to member dereferencement on incomplete type


Author: Albert<albrt2000@gmail.com>
Date: Wed, 10 Aug 2011 11:47:00 CST
Raw View
Hello,
Please consider
a.h
class A;
typedef void (A::*p_function)();
A *get_a_A();
p_function get_a_func_of_A();

a.cpp
#include "A.h"

class A
{
public:
     void dummy()
     {
     }
};
A a;

A *get_a_A()
{
     return&a;
}

p_function get_a_func_of_A()
{
     return&A::dummy;
}

and main.cpp
#include "a.h"

int main()
{
     (get_a_A()->*get_a_func_of_A())(); // (1) here is the problem
 return 0;
}


The only thing I found in the norm is 5.5 Pointer-to-member
operators :
"The binary operator ->* binds its second operand, which shall be of
type   pointer to member of T   (where
T is a **completely-defined** class type) to its first operand, which
shall be of type   pointer to T   or   pointer to
a class of which T is an unambiguous and accessible base class.   The
result is an object or a function of the
type specified by the second operand."

I expect having an error while compiling (1) according to this text.
But none of the compilers I tried neither static tools analysis
diagnostic this line as a problem.

Running it with MinGW succeeds, Visual generated code crashes (I
didn't try execution on other compilers)

So :
=>  Shall compiler diagnostic an error ?
=>  Is there any other line elsewhere in the norme stating it as an
undefined behaviour ?


I know that correction is quite simple : just define completly the
type but I was wondering if there is not something else.

Thanks in advance

Best regards.


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: =?windows-1252?Q?Daniel_Kr=FCgler?= <daniel.kruegler@googlemail.com>
Date: Thu, 11 Aug 2011 08:19:07 CST
Raw View
Am 10.08.2011 19:47, schrieb Albert:
>
> Please consider
> a.h
> class A;
> typedef void (A::*p_function)();
> A *get_a_A();
> p_function get_a_func_of_A();
>
> a.cpp
> #include "A.h"
>
> class A
> {
> public:
>      void dummy()
>      {
>      }
> };
> A a;
>
> A *get_a_A()
> {
>      return&a;
> }

To make your example more bullet-prove I suggest the following
modification of the definition of get_a_A():

A *get_a_A()
{
 static A a;
 return &a;
}

This ensures that the (now local) object 'a' is completely constructed
when get_a_A() is invoked. In your original example this is not
guaranteed since the global object 'a' (no longer needed in my
suggested fix) is completely constructed when get_a_A() is invoked.
Let me add that this modification does not change the
runtime-behaviour of your example for the compilers I tested.

> p_function get_a_func_of_A()
> {
>      return&A::dummy;
> }
>
> and main.cpp
> #include "a.h"
>
> int main()
> {
>      (get_a_A()->*get_a_func_of_A())(); // (1) here is the problem
>        return 0;
> }
>
>
> The only thing I found in the norm is 5.5 Pointer-to-member
> operators :
> "The binary operator ->* binds its second operand, which shall be of
> type   pointer to member of T   (where
> T is a **completely-defined** class type) to its first operand, which
> shall be of type   pointer to T   or   pointer to
> a class of which T is an unambiguous and accessible base class.   The
> result is an object or a function of the
> type specified by the second operand."
>
> I expect having an error while compiling (1) according to this text.
> But none of the compilers I tried neither static tools analysis
> diagnostic this line as a problem.
>
> Running it with MinGW succeeds, Visual generated code crashes (I
> didn't try execution on other compilers)
>
> So :
> =>   Shall compiler diagnostic an error ?

I tend to agree that the wording should be improved. IMO one can read
the "completely-defined type" requirement to belong to the "shall"
part of the sentence. But if that would be the case, any violation
would require a diagnostic. Failing that in practice the wording
should make clear that a violation of the complete-type requirement
does not require a diagnostic.

HTH & Greetings from Bremen,

- Daniel Kr   gler


--
[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Andreas Dehmel <blackhole.8.zarquon42@spamgourmet.com>
Date: Sat, 13 Aug 2011 10:19:00 CST
Raw View
On Wed, 10 Aug 2011 11:47:00 CST, Albert wrote:

[...]
> Running it with MinGW succeeds, Visual generated code crashes (I
> didn't try execution on other compilers)

This is most likely caused by an extremely dangerous ``optimization'' MSVC
has enabled by default (contrary to documented default behaviour) which means
that size and structure of p_function differ in compile units which know the
class structure and those which don't; the result of which is pretty much
instant death and a debugging context which makes no sense whatsoever. Compiling
with /vmg /vmv will probably fix it.



Andreas
--
Dr. Andreas Dehmel                           Ceterum censeo
FLIPME(ed.enilno-t@nouqraz)                  Microsoft esse delendam
http://www.zarquon.homepage.t-online.de          (Cato the Much Younger)


[ comp.std.c++ is moderated.  To submit articles, try posting with your ]
[ newsreader.  If that fails, use mailto:std-cpp-submit@vandevoorde.com ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]