Thread overview
extern intended behavior?
Jun 13, 2006
David Medlock
Jun 13, 2006
Derek Parnell
Jun 13, 2006
David Medlock
Jun 13, 2006
Sean Kelly
June 13, 2006
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
June 13, 2006
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
June 13, 2006
Derek Parnell wrote:
> On Tue, 13 Jun 2006 23:44:26 +1000, David Medlock <noone@nowhere.com>  wrote:
> 
<snip>
>> 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
June 13, 2006
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