http://gcc.gnu.org/bugzilla/show_bug.cgi?id=2316

--- Comment #25 from Marc Glisse <marc.glisse at normalesup dot org> 2011-08-30 
11:28:48 UTC ---
(In reply to comment #23)
> I think you can do it with a alias-declaration in an extern "C" block:
> 
> extern "C" {
>   template<typename T>
>     using func_type = T (*)();
> }
> 
> extern "C" void c() { }
> 
> template<typename T>
>   void f( func_type<T> p ) { p(); }
> 
> int main()
> {
>   f(&c);
> }
> 
> But yes, it's a bit of a hole in the type system that language linkage is part
> of the type but can only be specified in some contexts and can't be deduced by
> templates.

Yes, I thought about the alias, but it doesn't deduce the type. I really don't
think your example works unless you call f<thetype>(&c) as aliases are not
supposed to be deduced.

> We could solve it with an alternative syntax for language linkage
> using attributes:
> 
>   void f( [[extern(C)]] void (*p)() );

Is that where attributes go? That must be inconvenient for functions returning
function pointers. Or does it have some kind of "scope"?

> could be equivalent to:
> 
>   extern "C" {  typedef void (*func_type)();  }
>   void f( func_type p );
> 
> so we could say:
> 
>   template<typename T, typename U>
>     void g( [[extern(C)]] T (*p)(U));

Yes, that would be nice.

My guess is that we are supposed to use extern "C" functions very rarely and
only in very specific contexts where it doesn't matter so much if you can't do
all the meta-programming stuff.

> Anyway, that is probably straying off-topic for this PR.

Finding reasons to ask for the removal of this feature from the next standard
is kind of relevant ;-)

> Clang++ and VC++ also "implement" this bug.  If it's fixed in G++ it would 
> need
> to be controlled by a switch, maybe with the current behaviour as the default
> (but issuing a warning) for a couple of releases. As I said in c13, it could
> break a lot of code, plenty of people don't even know that they shouldn't be
> able to pass extern "C++" functions to C library APIs.

Oracle's compiler implements it as different types, which already breaks a bit
of code (but it also means that a number of large projects have been fixed for
it), but it still allows many kinds of conversions between them, so most code
only gives warnings.

Reply via email to