Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

splitting declaration from definition

Tags:

d

I really want to use D because its language constructions do so many things I care about better than C++, but the almost-forced GC (issue handled [sort of] here), slightly less powerful operator overloading (except opDispatch. opDispatch is sexy), and the following issue are kinda turning me off.

Is it possible in D to split a method declaration from a definition? If so, how? If not, why?

Motivating example for 'how': to provide a small header file of interface functions next to a binary object, as with a C header and library, for the sake of hiding the implementation away from the eyes of a writer of user code. Preference: without depending on whether or not the user code has hacked away the garbage collector or is simply compiling without druntime (such as this found in the comments here).

like image 563
user Avatar asked Apr 12 '26 12:04

user


2 Answers

If I write a D file like this one: http://arsdnet.net/dcode/iface/test.d and you compile with dmd -c, you'll see it goes without errors; that's a valid D file. The language allows you to write function prototypes without implementations.

A .di file is just like that, it just has a different file name.

Then given main: http://arsdnet.net/dcode/main.d if you compile dmd main, it will automatically search for iface/test.d when it sees "import iface.test;", find that .d file, or the .di if you rename it but same thing, and get your interface definition.

dmd main will fail with a linker error, so we need to implement it: http://arsdnet.net/dcode/impl.d Note: the impl does NOT import the module, so it never checks the other file. Keeping the .di and .d files in sync is one of the tricky parts here, unless you auto-generate the interface file, as undefined methods would give linker errors, but the order of methods is important: it must match, and so do the list of variables if there's any public ones. Otherwise, the usage code and the implementation code won't agree on the class' layout.

Again, it does not check that automatically, the implementation file doesn't look at the "header" file at all, so this is a major difference from C++ where you write the header file once, then use it in both the usage program and the implementation file.

You'll notice that the implementation file also lists the class, etc., too. D doesn't support the void MyClass::add(int a) {} syntax C++ has to write the method outside the class.

As far as I know, there's no way to force the implementation file to look for the header, if you put both on the command line, you get: "Error: module iface.test from file iface/test.d conflicts with another module test from file impl.d"

The way .di files are recommended to be used is to auto generate them with dmd -H. This reads the full implementation file and strips out the function bodies, leaving just the definitions. This part is probably the key thing when they say it is a feature of the compiler - the .di file is valid and standard D, but generated via a compiler option that doesn't necessarily need to be part of other compilers.

like image 139
Adam D. Ruppe Avatar answered Apr 18 '26 11:04

Adam D. Ruppe


You can declare functions without specifying their implementation by using extern, e.g.:

extern(D):
void foo(string name);

Then simply provide an object file/archive with the implementation for linking. Do note that the module name is part of the function's mangled name so either the header file needs the same module name as the compiled module or you can use extern(C) to disable mangling (precludes overloading and uses C call convention).

like image 20
Justin W Avatar answered Apr 18 '26 09:04

Justin W



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!