An interesting thing I learned while reading through some bug reports [1]:

cfile.c
#include <stdio.h>
void cfunction() {printf("hello\n");}

file1.d
module file1;
extern(C) void cfunction();

file2.d
module file2;
extern(C) void cfunction();

main.d
version(test1)
{
   import file1;
}
version(test2)
{
   import file2;
}

void main()
{
   cfunction();
}

cc -c cfile.c
dmd -version=test1 main.d file1.d file2.d cfile.o
./main
hello

dmd -version=test2 main.d file1.d file2.d cfile.o
./main
hello

All fine and good. Now:

dmd -version=test1 -version=test2 main.d file1.d file2.d cfile.o

main.d(12): Error: file2.cfunction at file2.d(2) conflicts with file1.cfunction at file1.d(2)

What gives here? cfunction is not part of any module, it's extern(C). In fact, both equate to the same symbol (as shown by the different ways we can import with only one implementation). But D considers them different. Why?

I would have expected that any time you declare (but don't define) an extern(C) symbol, it's just like a prototype -- if it's already declared no big deal. But it shouldn't be module-based.

Is there a good reason why we shouldn't allow the duplicate declaration in multiple modules? I understand for D symbols -- those are actually different symbols.

This is actually a problem someone may encounter quite a bit -- 2 different libraries or even modules from the same library (see referenced bug) may create their own bindings to C functions. I would say, let's just let the linker figure it out, no?

-Steve

[1] https://issues.dlang.org/show_bug.cgi?id=7729

Reply via email to