Title: ICE on VC7.0 (and VC6) attempting to resolve member function pointer
for a templated member function specialized by pointer-to-member-function
type (in case Newsgroups truncates it)

I have a piece of code that is supposed to be representative of a new
function-dispatching mechanism we're trying to implement. Here it is:

<CODE>
struct DispatchParameters {};
struct DispatchReturns {};

template<class Derived> struct Dispatcher
{
typedef void (Derived::*NOPARAMFUNC)();
typedef void (Derived::*LONGFUNC)(long);
typedef void (Derived::*DISPFUNC)(NOPARAMFUNC, const DispatchParameters&,
DispatchReturns&);

template<NOPARAMFUNC>
void dispatch(NOPARAMFUNC pFunc, const DispatchParameters&,
DispatchReturns&)
{
((static_cast<Derived*>(this))->*pFunc)();
}

template<LONGFUNC>
void dispatch(LONGFUNC pFunc, const DispatchParameters&, DispatchReturns& )
{
((static_cast<Derived*>(this))->*pFunc)(1L);
}
};

struct Sink: Dispatcher<Sink>
{
void P1();
void P2(long);
const DISPFUNC f1, f2;
Sink(): f1(reinterpret_cast<DISPFUNC>(&Sink::dispatch<&Sink::P1>)),
f2(reinterpret_cast<DISPFUNC>(&Sink::dispatch<&Sink::P2>)) {}
};

int main()
{
Sink sink;
return 0;
}
</CODE>

The idea is that in real code f1 and f2 will be replaced by entries in a
map, and macros uncannily similar to ATL's SINK_MAP_ENTRY etc will be used
to specify the map. The idea of the template parameters on the overloaded
dispatch functions in Dispatcher is to allow them to be disambiguated
depending on the function signature. I realise doing reinterpret_cast on a
member function pointer is not ideal, but I believe it is going to be safe
in the way I'm actually going to use it.

On both VC6 and VC7.0, an ICE occurs. I'm hardly surprised on VC6, but I had
hoped VC7 would be able to deal with this. I don't have VC7.1, Whidbey etc
so if someone here could try it out for me on that, that would be great. The
code above compiles without error with Comeau's online compiler.

(I don't need a solution to this problem. I am raising it as a conformance
issue only.)

Visual Studio 6.0, SP5 says:

EventSinkSandpit.cpp
c:\users\strew\scratchpad\eventsinksandpit\eventsinksandpit.cpp(35) : fatal
error C1001: INTERNAL COMPILER ERROR
(compiler file 'msc1.cpp', line 1794)

Visual Studio 7.0 (Microsoft Visual C++ .NET 55603-652-0000007-18379)
says:

Compiling...
EventSinkSandpit.cpp
c:\Documents and Settings\strew\My Documents\Visual Studio
Projects\EventSinkSandpit\EventSinkSandpit.cpp(31) : fatal error C1001:
INTERNAL COMPILER ERROR
(compiler file
'f:\vs70builds\9466\vc\Compiler\CxxFE\sl\p1\Cxx\grammar.y', line 9326)

Comeau (www.comeaucomputing.com/tryitout/) -- No errors.

Re: ICE on VC7.0 (and VC6) attempting to resolve member function pointer for a templated member function specialized by pointer-to-member-function type by Carl

Carl
Thu Jul 15 08:44:48 CDT 2004

Simon Trew wrote:
> On both VC6 and VC7.0, an ICE occurs. I'm hardly surprised on VC6,
> but I had hoped VC7 would be able to deal with this. I don't have
> VC7.1, Whidbey etc so if someone here could try it out for me on
> that, that would be great. The code above compiles without error with
> Comeau's online compiler.

Neither VC7.1 nor Whidbey compile the code, although neither ICEs. The
(rather old) Whidbey version I tried reports:

Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.40309 for 80x86
Copyright (C) Microsoft Corporation. All rights reserved.

templpmf0715.cpp
templpmf0715.cpp(30) : error C2440: 'specialization' : cannot convert from
'void (__thiscall Sink::* )(void)' to 'void (__thiscall Sink::*
const )(long)'
Types pointed to are unrelated; conversion requires
reinterpret_cast, C-style cast or function-style cast
templpmf0715.cpp(30) : error C2973: 'Dispatcher<Derived>::dispatch' :
invalid template argument 'void (__thiscall Sink::* )(void)'
with
[
Derived=Sink
]
templpmf0715.cpp(19) : see declaration of
'Dispatcher<Derived>::dispatch'
with
[
Derived=Sink
]
templpmf0715.cpp(31) : error C2440: 'reinterpret_cast' : cannot convert from
'overloaded-function' to 'void (__thiscall Sink::* )(long)'
None of the functions with this name in scope match the target type
templpmf0715.cpp(31) : fatal error C1903: unable to recover from previous
error(s); stopping compilation

Despite the fact that Comeau accepts the code, I'm not convinced that it
shouuld compile.. but I'm not prepared to make an argument as to why not :)

-cd



Re: ICE on VC7.0 (and VC6) attempting to resolve member function pointer for a templated member function specialized by pointer-to-member-function type by Joe

Joe
Fri Jul 16 16:25:35 CDT 2004

Simon Trew wrote:
> Title: ICE on VC7.0 (and VC6) attempting to resolve member function
> pointer for a templated member function specialized by
> pointer-to-member-function type (in case Newsgroups truncates it)
>
> I have a piece of code that is supposed to be representative of a new
> function-dispatching mechanism we're trying to implement. Here it is:
>
> <CODE>
> struct DispatchParameters {};
> struct DispatchReturns {};
>
> template<class Derived> struct Dispatcher
> {
> typedef void (Derived::*NOPARAMFUNC)();
> typedef void (Derived::*LONGFUNC)(long);
> typedef void (Derived::*DISPFUNC)(NOPARAMFUNC, const
> DispatchParameters&, DispatchReturns&);
>
> template<NOPARAMFUNC>
> void dispatch(NOPARAMFUNC pFunc, const DispatchParameters&,
> DispatchReturns&)
> {
> ((static_cast<Derived*>(this))->*pFunc)();
> }
>
> template<LONGFUNC>
> void dispatch(LONGFUNC pFunc, const DispatchParameters&,
> DispatchReturns& ) {
> ((static_cast<Derived*>(this))->*pFunc)(1L);
> }
> };
>
> struct Sink: Dispatcher<Sink>
> {
> void P1();
> void P2(long);
> const DISPFUNC f1, f2;
> Sink(): f1(reinterpret_cast<DISPFUNC>(&Sink::dispatch<&Sink::P1>)),
> f2(reinterpret_cast<DISPFUNC>(&Sink::dispatch<&Sink::P2>)) {}
> };
>
> int main()
> {
> Sink sink;
> return 0;
> }
> </CODE>
>
> The idea is that in real code f1 and f2 will be replaced by entries
> in a map, and macros uncannily similar to ATL's SINK_MAP_ENTRY etc
> will be used to specify the map. The idea of the template parameters
> on the overloaded dispatch functions in Dispatcher is to allow them
> to be disambiguated depending on the function signature. I realise
> doing reinterpret_cast on a member function pointer is not ideal, but
> I believe it is going to be safe in the way I'm actually going to use
> it.
>
> On both VC6 and VC7.0, an ICE occurs. I'm hardly surprised on VC6,
> but I had hoped VC7 would be able to deal with this. I don't have
> VC7.1, Whidbey etc so if someone here could try it out for me on
> that, that would be great. The code above compiles without error with
> Comeau's online compiler.
>
> (I don't need a solution to this problem. I am raising it as a
> conformance issue only.)
>
> Visual Studio 6.0, SP5 says:
>
> EventSinkSandpit.cpp
> c:\users\strew\scratchpad\eventsinksandpit\eventsinksandpit.cpp(35) :
> fatal error C1001: INTERNAL COMPILER ERROR
> (compiler file 'msc1.cpp', line 1794)
>
> Visual Studio 7.0 (Microsoft Visual C++ .NET
> 55603-652-0000007-18379) says:
>
> Compiling...
> EventSinkSandpit.cpp
> c:\Documents and Settings\strew\My Documents\Visual Studio
> Projects\EventSinkSandpit\EventSinkSandpit.cpp(31) : fatal error
> C1001: INTERNAL COMPILER ERROR
> (compiler file
> 'f:\vs70builds\9466\vc\Compiler\CxxFE\sl\p1\Cxx\grammar.y', line 9326)
>
> Comeau (www.comeaucomputing.com/tryitout/) -- No errors.

Simon,

I tried compiling the code with gcc 3.4.1, and this was the
result:

x.cpp: In constructor `Sink::Sink()':
x.cpp:30: error: address of overloaded function with no contextual type
information
x.cpp:30: confused by earlier errors, bailing out

So it looks like Comeau is probably the only compiler that
can compile it.

Unfortuntately, I don't know the language well enough to
know what is correct behavior in this case.


Joe



Re: ICE on VC7.0 (and VC6) attempting to resolve member function pointer for a templated member function specialized by pointer-to-member-function type by Simon

Simon
Mon Jul 19 03:53:59 CDT 2004

"Carl Daniel [VC++ MVP]" <cpdaniel_remove_this_and_nospam@mvps.org.nospam>
wrote in message news:ukmemHnaEHA.3508@TK2MSFTNGP09.phx.gbl...
>
> Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 14.00.40309 for
80x86
> Copyright (C) Microsoft Corporation. All rights reserved.
>
> templpmf0715.cpp
> templpmf0715.cpp(30) : error C2440: 'specialization' : cannot convert from
> 'void (__thiscall Sink::* )(void)' to 'void (__thiscall Sink::*
> const )(long)'
> Types pointed to are unrelated; conversion requires
> reinterpret_cast, C-style cast or function-style cast
>
> Despite the fact that Comeau accepts the code, I'm not convinced that it
> shouuld compile.. but I'm not prepared to make an argument as to why not
:)
>
> -cd

I am inclined to the same opinion; GNU and a.n.other compiler on UNIX also
produce similar complaints. But since Comeau compiles it I thought it was,
at the least, worth reporting a nonconformance in Comeau, if indeed it turns
out to be so. (I realise this is not the best place to report such a
nonconformance, but first things first...)

I have a vague memory of using an ADA compiler that (presumably) was
table-driven and inside the table they included a field with the section in
the LRM (language reference manual) that was being violated, so the error
message could quote it. IIRC, it even actually quoted the text of the LRM,
if you asked it nicely. This saved a lot of guesswork. I don't think I've
ever seen that with any C++ compiler. Of course, I realise that C++
compilers are rather more complicated beasts.

S.



Re: ICE on VC7.0 (and VC6) attempting to resolve member function pointer for a templated member function specialized by pointer-to-member-function type by Simon

Simon
Mon Jul 19 03:57:01 CDT 2004

"Carl Daniel [VC++ MVP]" <cpdaniel_remove_this_and_nospam@mvps.org.nospam>
wrote in message news:ukmemHnaEHA.3508@TK2MSFTNGP09.phx.gbl...
> Despite the fact that Comeau accepts the code, I'm not convinced that it
> shouuld compile.. but I'm not prepared to make an argument as to why not
:)
>

Yep, everything is sweet (on all platforms/compilers) when using a
reinterpret_cast instead of a static_cast.



Re: ICE on VC7.0 (and VC6) attempting to resolve member function pointer for a templated member function specialized by pointer-to-member-function type by tom_usenet

tom_usenet
Mon Jul 19 10:05:25 CDT 2004

On Thu, 15 Jul 2004 09:50:45 +0100, "Simon Trew"
<noneofyour@business.guv> wrote:

>Title: ICE on VC7.0 (and VC6) attempting to resolve member function pointer
>for a templated member function specialized by pointer-to-member-function
>type (in case Newsgroups truncates it)
>
>I have a piece of code that is supposed to be representative of a new
>function-dispatching mechanism we're trying to implement. Here it is:

[code]

Here's a simplified version that exhibits the problem:
template<void()>
void dispatch()
{
}

template<void(long)>
void dispatch()
{
}

void P1();
void P2(long);

int main()
{
dispatch<P1>();
dispatch<P2>();
}

The question is, is the above legal? Comeau compiles it, VC7.1
doesn't.

I can't find anything in the standard about this. Basically, can
explicit argument specification choose a function template overload
based on the passes type of a non-type template parameter?

Tom

Re: ICE on VC7.0 (and VC6) attempting to resolve member function pointer for a templated member function specialized by pointer-to-member-function type by Simon

Simon
Wed Jul 21 02:02:02 CDT 2004

"tom_usenet" <tom_usenet@hotmail.com> wrote in message
news:pbmnf0tq5pl11bpb5dkv5ga5fnqc9k5rdf@4ax.com...
> On Thu, 15 Jul 2004 09:50:45 +0100, "Simon Trew"
> <noneofyour@business.guv> wrote:
>
> Here's a simplified version that exhibits the problem:
> template<void()>
> void dispatch()
> {
> }
>
> template<void(long)>
> void dispatch()
> {
> }
>
> void P1();
> void P2(long);
>
> int main()
> {
> dispatch<P1>();
> dispatch<P2>();
> }
>
> The question is, is the above legal? Comeau compiles it, VC7.1
> doesn't.
>
> I can't find anything in the standard about this. Basically, can
> explicit argument specification choose a function template overload
> based on the passes type of a non-type template parameter?
>
> Tom

Presactly. Thanks for finding a more condensed example. I thought it was
because the types were pointers to non-static member functions, but the same
problem seems to present itself for pointers to other functions, too.