|Posted by Anders F Björklund|
in reply to zwang
>> Is there any way to forward declarate a class?
>> When I try to do it... the compiler says that forward declaration conflicts with the real declaration.
>> I can work around the problem using cross imports between modules, is it a good practice?
> The doc says:
> "The program is looked at as a whole, and so not only is it not necessary to code forward declarations, it is not even allowed! "
However, if you need to provide D source modules
for symbols that will be defined elsewhere - then
you can do so called "import modules" (a.k.a. stubs).
They are similar to the regular code, but without
the implementation body that regularly follows...
See this example, from object.d:
> class Object
> void print();
> char toString();
> uint toHash();
> int opCmp(Object o);
> int opEquals(Object o);
That compiles alright, and when you link it then
it uses the implementation from internal/object.d
(that is contained in the "phobos" object library)
They both have the declaration: module object;
Thus you can ship one public "import module",
while keeping the implementation in a library.
(if you for some reason dislike Open Source)
This is similar to how you declare C functions,
in "import modules" for D usage. The only caveat
there is that any variables in it will be defined.
> extern (C) int variable; // declares "variable"!
This differs greatly from C/C++ headers,
where any "extern" variable declarations
will not be defined. But again, D is not C...
So if you need to import data symbols, then
you put those statements in *another* module,
which you then import from the import module...
Here's an example, for the "whatever" library:
> // import module for whatever
> module whatever;
> private import whateverextern;
> extern (C) void function();
> // extern module for whatever
> module whateverextern;
> extern (C) int variable;
The data module is called an "extern module", and
should *not* be compiled into the program - instead
you link against the C or D library you want to import.
std.c.linux and std.c.linuxextern are good examples
of using this to import data symbols from a C library.
(it can also be used for D code, by omitting "extern")
Confusing? Normally it isn't needed, and you can just
dump all your source code on "dmd" to compile and link...
(and having public data symbols in libraries is illegal
in three states already, and should be avoided if possible)
But the import modules comes in handy once, in a while.
(and there should be a tool to *automatically* create
them from the implementation, to avoid duplication...)