extern(C) symbol conflicts

Steven Schveighoffer via Digitalmars-d digitalmars-d at puremagic.com
Mon Jan 26 11:06:49 PST 2015


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


More information about the Digitalmars-d mailing list