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 ]