Thread overview
extern(Windows) alias bug
May 29, 2006
John C
May 29, 2006
Regan Heath
May 30, 2006
John C
Jun 02, 2006
Walter Bright
May 30, 2006
Lionello Lunesu
May 30, 2006
John C
May 30, 2006
Lionello Lunesu
Jun 02, 2006
Walter Bright
May 29, 2006
The following are not equivalent, though I can't understand why not.

template TFunc1() {
  extern(Windows) alias int function(int) TFunc1;
}

alias int function(int) funcA;
template TFunc2() {
  extern(Windows) alias funcA TFunc2;
}

void main() {
  writefln(TFunc1!().mangleof); // PWiZi
  writefln(TFunc2!().mangleof); // PFiZi
}

So the extern(Windows) gets applied to TFunc1, but not TFunc2.
May 29, 2006
On Mon, 29 May 2006 22:50:23 +0100, John C <johnch_atms@hotmail.com> wrote:
> The following are not equivalent, though I can't understand why not.
>
> template TFunc1() {
>    extern(Windows) alias int function(int) TFunc1;
> }
>
> alias int function(int) funcA;
> template TFunc2() {
>    extern(Windows) alias funcA TFunc2;
> }
>
> void main() {
>    writefln(TFunc1!().mangleof); // PWiZi
>    writefln(TFunc2!().mangleof); // PFiZi
> }
>
> So the extern(Windows) gets applied to TFunc1, but not TFunc2.

At a wild guess.. doesn't the alias:
  alias int function(int) funcA;

have an implicit "D calling convention" (extern(D)?) label/tag/specifier, eg.
  alias extern(D) int function(int) funcA;

so, the alias:
  extern(Windows) alias funcA TFunc2;

really reads something like:
  extern(Windows) alias extern(D) int function(int) TFunc2;

and maybe the later one overrules the former?

Regan
May 30, 2006
Regan Heath wrote:
> On Mon, 29 May 2006 22:50:23 +0100, John C <johnch_atms@hotmail.com> wrote:
> 
>> The following are not equivalent, though I can't understand why not.
>>
>> template TFunc1() {
>>    extern(Windows) alias int function(int) TFunc1;
>> }
>>
>> alias int function(int) funcA;
>> template TFunc2() {
>>    extern(Windows) alias funcA TFunc2;
>> }
>>
>> void main() {
>>    writefln(TFunc1!().mangleof); // PWiZi
>>    writefln(TFunc2!().mangleof); // PFiZi
>> }
>>
>> So the extern(Windows) gets applied to TFunc1, but not TFunc2.
> 
> 
> At a wild guess.. doesn't the alias:
>   alias int function(int) funcA;
> 
> have an implicit "D calling convention" (extern(D)?) label/tag/specifier,  eg.
>   alias extern(D) int function(int) funcA;
> 
> so, the alias:
>   extern(Windows) alias funcA TFunc2;
> 
> really reads something like:
>   extern(Windows) alias extern(D) int function(int) TFunc2;
> 
> and maybe the later one overrules the former?
> 
> Regan

You may be right there. The reason why I wanted this to work is because this doesn't:

template TFunc(T) {
  ...
}

TFunc!(extern(Windows) int function(int));

A nice workaround would have been to have another template apply the calling convention:

template ExternWindows(T) {
  extern(Windows) alias T ExternWindows;
}

TFunc!(ExternWindows!(int function(int, char*, char*, int));

I guess I'm now wondering why extern can't be used inline. It'd be useful in the above situation, and on anonymous function literals.

John.
May 30, 2006
John C wrote:
> The following are not equivalent, though I can't understand why not.
> 
> template TFunc1() {
>   extern(Windows) alias int function(int) TFunc1;
> }
> 
> alias int function(int) funcA;
> template TFunc2() {
>   extern(Windows) alias funcA TFunc2;
> }
> 
> void main() {
>   writefln(TFunc1!().mangleof); // PWiZi
>   writefln(TFunc2!().mangleof); // PFiZi
> }
> 
> So the extern(Windows) gets applied to TFunc1, but not TFunc2.

I think you put the "extern" on the wrong place:

template TFunc1() {
  alias extern(Windows) int function(int) TFunc1;
}

alias int function(int) funcA;
template TFunc2() {
  alias extern(Windows) funcA TFunc2;
}

alias extern(Windows) int function(int) funcB;
template TFunc3() {
  alias funcB TFunc3;
}

void main()
{
  writefln(TFunc1!().mangleof); // PFiZi
  writefln(TFunc2!().mangleof); // PFiZi
  writefln(funcA.mangleof); // PFiZi
  writefln(funcB.mangleof); // PFiZi
  writefln(TFunc3!().mangleof); // PFiZi
}

L.
May 30, 2006
Lionello Lunesu wrote:
> John C wrote:
> 
>> The following are not equivalent, though I can't understand why not.
>>
>> template TFunc1() {
>>   extern(Windows) alias int function(int) TFunc1;
>> }
>>
>> alias int function(int) funcA;
>> template TFunc2() {
>>   extern(Windows) alias funcA TFunc2;
>> }
>>
>> void main() {
>>   writefln(TFunc1!().mangleof); // PWiZi
>>   writefln(TFunc2!().mangleof); // PFiZi
>> }
>>
>> So the extern(Windows) gets applied to TFunc1, but not TFunc2.
> 
> 
> I think you put the "extern" on the wrong place:
> 
> template TFunc1() {
>   alias extern(Windows) int function(int) TFunc1;
> }
> 
> alias int function(int) funcA;
> template TFunc2() {
>   alias extern(Windows) funcA TFunc2;
> }
> 
> alias extern(Windows) int function(int) funcB;
> template TFunc3() {
>   alias funcB TFunc3;
> }
> 
> void main()
> {
>   writefln(TFunc1!().mangleof); // PFiZi
>   writefln(TFunc2!().mangleof); // PFiZi
>   writefln(funcA.mangleof); // PFiZi
>   writefln(funcB.mangleof); // PFiZi
>   writefln(TFunc3!().mangleof); // PFiZi
> }
> 
> L.

No, "extern" has to go before "alias". In your code the calling convention has been ignored. And mangleof shows that: 'F' signifies functions with the D calling convention, 'W' functions with the Windows calling convention.
May 30, 2006
John C wrote:
> No, "extern" has to go before "alias". In your code the calling convention has been ignored. And mangleof shows that: 'F' signifies functions with the D calling convention, 'W' functions with the Windows calling convention.

I stand corrected then :)
Too bad the compiler does not complain, I even compiled it with warnings on.

L.
June 02, 2006
John C wrote:
> The following are not equivalent, though I can't understand why not.
> 
> template TFunc1() {
>   extern(Windows) alias int function(int) TFunc1;
> }
> 
> alias int function(int) funcA;
> template TFunc2() {
>   extern(Windows) alias funcA TFunc2;
> }
> 
> void main() {
>   writefln(TFunc1!().mangleof); // PWiZi
>   writefln(TFunc2!().mangleof); // PFiZi
> }
> 
> So the extern(Windows) gets applied to TFunc1, but not TFunc2.

That's right. An alias does not modify the calling convention of whatever it is calling. It cannot, it is just another name for it.
June 02, 2006
John C wrote:
> You may be right there. The reason why I wanted this to work is because this doesn't:
> 
> template TFunc(T) {
>   ...
> }
> 
> TFunc!(extern(Windows) int function(int));
> 
> A nice workaround would have been to have another template apply the calling convention:
> 
> template ExternWindows(T) {
>   extern(Windows) alias T ExternWindows;
> }
> 
> TFunc!(ExternWindows!(int function(int, char*, char*, int));

Try:

	extern (Windows) alias int function(int) fp;