www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - extern intended behavior?

reply David Medlock <noone nowhere.com> writes:
Look at the following source files(main.d and test.d):

// main.d  ----------------------
extern
{
   void MyFunction();
}

void main(char[][] args )
{
   MyFunction();
}


// test.d ----------------------

import std.stdio;

void MyFunction()
{
   writefln("Hello World");
}

compiles fine, but linker complains:
  Error 42: Symbol Undefined _D4main10MyFunctionFZv
--- errorlevel 1


It appears the linker expects the extern function to be in the 'main' 
module.  This appears to be incorrect behavior.  If it isn't why such a 
departure from a common C idiom(lex and yacc).

Am I missing something?
-DavidM
Jun 13 2006
next sibling parent reply "Derek Parnell" <derek psych.ward> writes:
On Tue, 13 Jun 2006 23:44:26 +1000, David Medlock <noone nowhere.com>  
wrote:

 Look at the following source files(main.d and test.d):

 // main.d  ----------------------
 extern
 {
    void MyFunction();
 }

 void main(char[][] args )
 {
    MyFunction();
 }


 // test.d ----------------------

 import std.stdio;

 void MyFunction()
 {
    writefln("Hello World");
 }

 compiles fine, but linker complains:
   Error 42: Symbol Undefined _D4main10MyFunctionFZv
 --- errorlevel 1


 It appears the linker expects the extern function to be in the 'main'  
 module.  This appears to be incorrect behavior.

No its not. This is intentional.
 If it isn't why such a departure from a common C idiom(lex and yacc).

Don't know.
 Am I missing something?

Yes. The way to do this is D is that you also create another file 'test.di' that contains ... // test.di -------------------- void MyFunction(); And you modify main.d // main.d ---------------------- import test; void main(char[][] args ) { MyFunction(); } Then you compile them as ... dmd -c test dmd main test.obj -- Derek Parnell Melbourne, Australia
Jun 13 2006
parent David Medlock <noone nowhere.com> writes:
Derek Parnell wrote:
 On Tue, 13 Jun 2006 23:44:26 +1000, David Medlock <noone nowhere.com>  
 wrote:
 

 Am I missing something?

Yes. The way to do this is D is that you also create another file 'test.di' that contains ... // test.di -------------------- void MyFunction(); And you modify main.d // main.d ---------------------- import test; void main(char[][] args ) { MyFunction(); } Then you compile them as ... dmd -c test dmd main test.obj

Thanks Derek. It appears you can also just wrap them both with extern(C) and leave them in D files. -DavidM
Jun 13 2006
prev sibling parent Sean Kelly <sean f4.ca> writes:
David Medlock wrote:
 Look at the following source files(main.d and test.d):
 
 // main.d  ----------------------
 extern
 {
   void MyFunction();
 }
 
 void main(char[][] args )
 {
   MyFunction();
 }
 
 
 // test.d ----------------------
 
 import std.stdio;
 
 void MyFunction()
 {
   writefln("Hello World");
 }
 
 compiles fine, but linker complains:
  Error 42: Symbol Undefined _D4main10MyFunctionFZv
 --- errorlevel 1
 
 
 It appears the linker expects the extern function to be in the 'main' 
 module.  This appears to be incorrect behavior.  If it isn't why such a 
 departure from a common C idiom(lex and yacc).
 
 Am I missing something?

In D the symbol name is based on the module name, which is equivalent to the file name in the absence of a module statement. For this reason, "extern (D)" has very limited use. Generally, I'll only use it if I'm doing something like this: extern (C): ... extern (D) void inlineFunc() {} Sean
Jun 13 2006