4

If you really need to, you can specify __attribute__((weak)) in C (see scriptedmain). This allows a program to double as API and executable, allowing code that imports the API to overwrite the main function.

Does D have a way to do this? Python has if __name__=="__main__": main(), but the weak syntax in C seems much closer.

mcandre
  • 22,868
  • 20
  • 88
  • 147

3 Answers3

6

Yes, using version directives, which require special options to rdmd and dmd.

scriptedmain.d:

#!/usr/bin/env rdmd -version=scriptedmain

module scriptedmain;

import std.stdio;

int meaningOfLife() {
    return 42;
}

version (scriptedmain) {
    void main(string[] args) {
        writeln("Main: The meaning of life is ", meaningOfLife());
    }
}

test.d:

#!/usr/bin/env rdmd -version=test

import scriptedmain;
import std.stdio;

version (test) {
    void main(string[] args) {
        writeln("Test: The meaning of life is ", meaningOfLife());
    }
}

Example:

$ ./scriptedmain.d
Main: The meaning of life is 42
$ ./test.d
Test: The meaning of life is 42
$ dmd scriptedmain.d -version=scriptedmain
$ ./scriptedmain
Main: The meaning of life is 42
$ dmd test.d scriptedmain.d -version=test
$ ./test
Test: The meaning of life is 42

Also posted on RosettaCode.

mcandre
  • 22,868
  • 20
  • 88
  • 147
  • 2
    Technically you are not overriding main but using conditional compilation. It's closer to an `#ifdef` then to `__attribute__`. – RedX Oct 18 '11 at 11:39
  • you can use `pragma(startaddress,foo)` wrapped in version statements to get the same result without wrapping the main functions in versions – ratchet freak Oct 20 '11 at 08:40
  • @ratchetfreak Cool! Please give a full example of its usage. – mcandre Oct 20 '11 at 15:07
2

I believe __attribute__((weak)) is a GNU extension which emits special linker instructions for weak linking, so it's very toolchain-specific. There is nothing in DMD for this AFAIK, but other D compilers (GDC or LDC) may support their backends' extensions.

Vladimir Panteleev
  • 24,651
  • 6
  • 70
  • 114
0

IIRC there is a way to get code to compile to a library rather than an object file. Because of the way the linker searches for things, you can use that to get the same effect; just put the target with the main you want to use first in the link order.

BCS
  • 75,627
  • 68
  • 187
  • 294