how to implement a function in a different D source file

mipri mipri at minimaltype.com
Tue Nov 26 03:45:26 UTC 2019


On Tuesday, 26 November 2019 at 03:06:52 UTC, Omar wrote:
> Hey, I'm very interested in this programming language, I 
> already prefer it to C++ and if only i had adopted it years 
> ago, but that's beside the point.
>
> I read a bunch of tuts today and the only thing I'm really 
> stuck on at the moment is how to actually implement a function 
> in a different file.
>
> the page here https://dlang.org/spec/function.html
> suggests you can implement a function in a different file, and 
> a different tutorial somewhere else (or maybe the same site or 
> even same page idr) mentioned the endeavour of 
> no-bodied-functions as a way of presenting a black-box type of 
> interface.
>
> But with the whole module namespace thing I'm a bit at a loss 
> how to do this.
> Say I have main.d ex.d and ex2.d and I want to import ex, and 
> call a function it
> declares, and implement the function in ex2.d and link the 
> objects at the end so the linker is happy. I don't know how to 
> do this and I can't find a straigh answer anywhere or any 
> examples.
>
> so ?

First, here's exactly what you're asking for:

   $ cat ex1.d
   enum string admin = "Dave";

   $ cat ex2.d
   import ex1;

   string greeting() {
       return "Hello, " ~ admin;
   }

   $ cat main.d
   import ex2;

   void main() {
       import std.stdio: writeln;
       writeln(greeting);
   }

Three files that all import what they need, and can be
compiled separately and then linked.

   $ dmd -c ex1
   $ dmd -c ex2
   $ dmd -c main
   $ dmd -ofmain main.o ex2.o ex1.o
   $ ./main
   Hello, Dave

And dmd isn't cheating, as you can see by skipping the first
two compiles:

   $ rm *.o
   $ dmd -c main
   $ dmd -ofmain main.o
   /usr/bin/ld: main.o: in function `_Dmain':
   main.d:(.text._Dmain[_Dmain]+0x5): undefined reference to 
`_D3ex28greetingFZAya'
   collect2: error: ld returned 1 exit status
   Error: linker exited with status 1

But you could also just compile everything together:

   $ rm *.o
   $ dmd -ofmain *.d
   $ ./main
   Hello, Dave

If all of your code is in D, my received understanding is that
this is a completely reasonable option.

You could also use dub as your build system:

   Package recipe format (sdl/json) [json]:
   Name [main]:
   Description [A minimal D application.]:
   Author name [mipri]:
   License [proprietary]: MIT
   Copyright string [Copyright © 2019, mipri]:
   Add dependency (leave empty to skip) []:

This'll create a new directory named 'main', and you can build
and run a 'hello world' by running 'dub'.

After moving some files around...

   $ cat source/movie/references/names.d
   module movie.references.names;

   enum string admin = "Dave";

   $ cat source/movie/references/lines.d
   module movie.references.lines;

   string cantDoThat() {
       import movie.references.names: admin;
       return "I'm afraid I can't do that, " ~ admin;
   }

   $ cat source/app.d
   void main() {
       import movie.references.lines: cantDoThat;
       import std.stdio: writeln;
       writeln(cantDoThat);
   }

Building and running it:

   $ dub
   Performing "debug" build using dmd for x86_64.
   main ~master: building configuration "application"...
   Linking...
   Running ./main
   I'm afraid I can't do that, Dave




More information about the Digitalmars-d-learn mailing list