www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.bugs - extern(Windows) alias bug

reply John C <johnch_atms hotmail.com> writes:
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
next sibling parent reply "Regan Heath" <regan netwin.co.nz> writes:
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 29 2006
parent reply John C <johnch_atms hotmail.com> writes:
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
parent Walter Bright <newshound digitalmars.com> writes:
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;
Jun 02 2006
prev sibling next sibling parent reply Lionello Lunesu <lio lunesu.remove.com> writes:
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
parent reply John C <johnch_atms hotmail.com> writes:
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
parent Lionello Lunesu <lio lunesu.remove.com> writes:
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.
May 30 2006
prev sibling parent Walter Bright <newshound digitalmars.com> writes:
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.
Jun 02 2006