January 12, 2007
Marcio Faustino Wrote:

> Even so, the compiler says that
> "object.printf" conflicts with "my_printf.printf"... but where??

It's declared in two places, and so when you call "printf" in test.d, it finds two printfs.  It's a simple matter of symbol lookup -- one name in this case maps to more than one possible function.  So the conflict occurs at the call site, which can be fixed by using either an FQN or an alias, as mentioned.

If you were linking against some C stdlib that didn't have an implementation of printf, the fix is very simple -- comment out the printf declaration in object.d.
January 12, 2007
Frits van Bommel wrote:
> 
> You're writing forward declarations. Seriously, D doesn't need them; forward references are allowed ;).
> 
> A function declaration without definition is for when you put the definition in a different file, not to put it later in the same file.

I think the same conflict can occur in this situation though:

    module a;

    extern (C) void fn();

    module b;

    extern (C) void fn();

    module c;

    import a, b;

    void main()
    {
        fn();
    }

This one has bitten me a few times where I had declared the prototype for a C library routine to avoid importing the entire header module, and a derived module imported both my module and the C header module.  Even worse, the same error will occur if one of the two declarations is private, because of how symbol resolution is handled.  This makes the approach outlined above completely intractable, and actually more restrictive than C where multiple prototypes of the same function are allowed.


Sean
January 12, 2007
Marcio Faustino wrote:
> Frits van Bommel wrote:
>> 'printf' is problematic because object.d (which is automatically
>> imported into every D module) also declares it.
>>
>> That code might otherwise compile, but I'm not sure what would happen at
>> the linking stage; printf is also defined in the C runtime library which
>> is linked to by default. It might just use one of the two, or it might fail.
> 
> But the problem is that the code *does not* compile with the line that says
> "Error" uncommented. Without getting into linking details, the compiler *should*
> accept the given definition because "object.d" and "internal/object.d" only
> contain declarations of the printf function.
> 
> Am I wrong?

The compiler sees two declarations for printf, in different modules. It sees these as different functions as one is 'object.printf' and the other is 'my_printf.printf'. The easiest ways to solve this ambiguity are
(1) rename your printf ;).
(2) add 'alias my_printf.printf printf' to your test.d to make it clear which printf you want.
(3) change the import line to 'import my_printf : printf' to import only printf from that module and additionally get the effect of (2).

I know it seems a bit silly to have to disambiguate between two declarations that will generate the exact same machine code when called (including the called address) but D's name resolution was probably designed with name mangling in mind...
January 12, 2007
Marcio Faustino wrote:
> Stewart Gordon wrote:
>> You've more or less answered your own question: use a fully-qualified
>> name.  Alternatively, use in test.d
>>
>>      alias my_printf.printf printf;
> 
> That's a nice alternative, but I don't want to use that. Suppose someone were
> writing a kernel, then the compiler should accept the printf definition he gave
> because he won't link against the C library. Even so, the compiler says that
> "object.printf" conflicts with "my_printf.printf"... but where??

If one is writing a kernel, one probably modifies object.d ;).
At least, that's what I did...
(Actually, printf was the first thing to get removed :P)
January 12, 2007
Sean Kelly wrote:
> This one has bitten me a few times where I had declared the prototype for a C library routine to avoid importing the entire header module, and a derived module imported both my module and the C header module.  Even worse, the same error will occur if one of the two declarations is private, because of how symbol resolution is handled.  This makes the approach outlined above completely intractable, and actually more restrictive than C where multiple prototypes of the same function are allowed.

What's wrong with importing the entire header module?  That's what modules are designed for: avoiding declaring the same function multiple times.  They also don't add any code bloat.
January 12, 2007
Thanks for all the replies, I think I understand it now.

Frits van Bommel wrote:
> If one is writing a kernel, one probably modifies object.d ;).
> At least, that's what I did...
> (Actually, printf was the first thing to get removed :P)

The downside of modifying "object.d" is that you'll end up having a mini-phobos library with only the stuff you need, right?

As for your kernel, can I see the source code? :-)
January 12, 2007
Marcio Faustino wrote:
> Thanks for all the replies, I think I understand it now.
> 
> Frits van Bommel wrote:
>> If one is writing a kernel, one probably modifies object.d ;).
>> At least, that's what I did...
>> (Actually, printf was the first thing to get removed :P)
> 
> The downside of modifying "object.d" is that you'll end up having a mini-phobos
> library with only the stuff you need, right?

That's what happens with any kernel project in any language higher than C (i.e. any language that needs some form of runtime). Though some C compilers may generate implicit memcpy() calls etc., so I guess that counts...

> As for your kernel, can I see the source code? :-)

It doesn't do much of any use currently. It just boots and shows some status messages while initializing the system.
Then it just sits there, echoing keyboard input.
It doesn't even clean up after itself (no way of freeing allocated memory). I plan on implementing or porting a GC some day, but at the moment it doesn't use enough memory to make it worth freeing.

I just think it should be at least marginally functional before I go spreading the source around :).
January 12, 2007
Sean Kelly wrote:
> Frits van Bommel wrote:
>>
>> You're writing forward declarations. Seriously, D doesn't need them; forward references are allowed ;).
>>
>> A function declaration without definition is for when you put the definition in a different file, not to put it later in the same file.
> 
> I think the same conflict can occur in this situation though:
> 
>     module a;
> 
>     extern (C) void fn();
> 
>     module b;
> 
>     extern (C) void fn();
> 
>     module c;
> 
>     import a, b;
> 
>     void main()
>     {
>         fn();
>     }
> 
> This one has bitten me a few times where I had declared the prototype for a C library routine to avoid importing the entire header module, and a derived module imported both my module and the C header module.  Even worse, the same error will occur if one of the two declarations is private, because of how symbol resolution is handled.  This makes the approach outlined above completely intractable, and actually more restrictive than C where multiple prototypes of the same function are allowed.

You cut that quote a bit short. Reread the rest of that paragraph at the end of your quote.
What I was talking about was more in the line of Phobos' object.d & internal/object.d, or a C source file and its D import module.
Either way, only one of the files is intended to be imported (but shouldn't get compiled itself). The other file then gets compiled and linked in its place.
January 12, 2007
Tyler Knott wrote:
> Sean Kelly wrote:
>> This one has bitten me a few times where I had declared the prototype for a C library routine to avoid importing the entire header module, and a derived module imported both my module and the C header module.  Even worse, the same error will occur if one of the two declarations is private, because of how symbol resolution is handled.  This makes the approach outlined above completely intractable, and actually more restrictive than C where multiple prototypes of the same function are allowed.
> 
> What's wrong with importing the entire header module?  That's what modules are designed for: avoiding declaring the same function multiple times.  They also don't add any code bloat.

In the past, there were some issues with D where importing even empty modules bloated the executable quite noticeably (I think it was ~500 bytes per empty module).  This appeared related to ModuleInfo that was generated apparently regardless of whether it was necessary.  I re-tested this recently, however, and was unable to reproduce my old results, so I think this problem has been fixed as a side-effect of other changes.  Still, there are some places in my code where I have declarations of C routines rather than imports, as I haven't gone to the trouble of changing them now that this seems to have been resolved.


Sean
January 12, 2007
Frits van Bommel wrote:
> 
> You cut that quote a bit short. Reread the rest of that paragraph at the end of your quote.
> What I was talking about was more in the line of Phobos' object.d & internal/object.d, or a C source file and its D import module.
> Either way, only one of the files is intended to be imported (but shouldn't get compiled itself). The other file then gets compiled and linked in its place.

Fair enough.  I replied mostly because I thought it may be useful to mention a related issue I'd encountered in the past.  My apologies if the implication was otherwise.


Sean
1 2
Next ›   Last »