January 12, 2007
Hi everyone,

How can I create a function declaration only and provide its definition later? For example:

/******************************************************************************/
extern (C) int print(char*);

extern (C) int print(char* s) {
    return printf("%s", s);
}

void main() {
    print(cast(char*) "test\0");
}
/******************************************************************************/

The compiler says:
«test.d(9): function test.print called with argument types:
        (char*)
matches both:
        test.print(char*)
and:
        test.print(char*)»

What am I doing wrong?
Thanks,
January 12, 2007
Marcio Faustino wrote:
> Hi everyone,
> 
> How can I create a function declaration only and provide its definition later?
> For example:
> 
> /******************************************************************************/
> extern (C) int print(char*);
> 
> extern (C) int print(char* s) {
>     return printf("%s", s);
> }
> 
> void main() {
>     print(cast(char*) "test\0");
> }
> /******************************************************************************/
> 
> The compiler says:
> «test.d(9): function test.print called with argument types:
>         (char*)
> matches both:
>         test.print(char*)
> and:
>         test.print(char*)»
> 
> What am I doing wrong?
> Thanks,

Nothing.  I think the implementation needs to be in a separate file if you want separate compilation like that.  Though it would admittedly be nice if the compiler could recognize that there is no actual conflict between a declaration and an implementation of the same function.


Sean
January 12, 2007
Marcio Faustino wrote:
> Hi everyone,
> 
> How can I create a function declaration only and provide its definition later? For example:


If you meant a "foreward declaration": this is not possible in D.
January 12, 2007
rochus schrieb:
> Marcio Faustino wrote:
>> Hi everyone,
>>
>> How can I create a function declaration only and provide its definition later? For example:
> 
> 
> If you meant a "foreward declaration": this is not possible in D.

In the normal case, something like that is not needed.

For libs, there is the possibilty to generate headers. For dmd use the -H option. The generated .di files will contain all declarations the compiler needs to compile a module.
January 12, 2007
Marcio Faustino wrote:
> How can I create a function declaration only and provide its definition later?

You can't. Not in the same file, at least.[1]

> For example:
> 
> /******************************************************************************/
> extern (C) int print(char*);
> 
> extern (C) int print(char* s) {
>     return printf("%s", s);
> }
> 
> void main() {
>     print(cast(char*) "test\0");
> }
> /******************************************************************************/
> 
> The compiler says:
> «test.d(9): function test.print called with argument types:
>         (char*)
> matches both:
>         test.print(char*)
> and:
>         test.print(char*)»


> What am I doing wrong?

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.
It's mostly useful to link to libraries designed to link to C, though Phobos also uses it in object.d to link to definitions in internal/object.d.
It *could* also be useful to link to closed-source D libraries, but I haven't seen any yet...



[1]: I just had an evil idea. Turns out it's technically possible.
You can declare extern(C) it with a different argument type, then both overloads will have the same name in the executable (no name mangling) and the linker will link them both to the same definition.
But I wouldn't use this for anything serious, and I wouldn't have been surprised if it hadn't worked at all due to a symbol conflict or something.
January 12, 2007
> 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.
> It's mostly useful to link to libraries designed to link to C, though
> Phobos also uses it in object.d to link to definitions in internal/object.d.
> It *could* also be useful to link to closed-source D libraries, but I
> haven't seen any yet...

So, how can I do something like this:

/*[ my_printf.d ]**************************************************************/ module my_printf;

extern (C) int printf(char* format, ...) {
	return 0;    // Just to test.
}
/******************************************************************************/
/*[ test.d ]*******************************************************************/
import my_printf;

void main() {
	//printf("test\0");            // Error.
	my_printf.printf("test\0");    // Ok.
}
/******************************************************************************/

Because the line with "Error" uncommented, the compiler says:
«test.d(5): Error: object.printf at /home/marcio/dmd/src/phobos/object.d(14)
conflicts with my_printf.printf at my_printf.d(3)»
January 12, 2007
Marcio Faustino wrote:
> So, how can I do something like this:
> 
> /*[ my_printf.d ]**************************************************************/
> module my_printf;
> 
> extern (C) int printf(char* format, ...) {
> 	return 0;    // Just to test.
> }
> /******************************************************************************/
> /*[ test.d ]*******************************************************************/
> import my_printf;
> 
> void main() {
> 	//printf("test\0");            // Error.
> 	my_printf.printf("test\0");    // Ok.
> }
> /******************************************************************************/
> 
> Because the line with "Error" uncommented, the compiler says:
> «test.d(5): Error: object.printf at /home/marcio/dmd/src/phobos/object.d(14)
> conflicts with my_printf.printf at my_printf.d(3)»

'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.
January 12, 2007
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?
January 12, 2007
Marcio Faustino wrote:
<snip>
> /*[ test.d ]*******************************************************************/
> import my_printf;
> 
> void main() {
> 	//printf("test\0");            // Error.
> 	my_printf.printf("test\0");    // Ok.
> }
> /******************************************************************************/
> 
> Because the line with "Error" uncommented, the compiler says:
> «test.d(5): Error: object.printf at /home/marcio/dmd/src/phobos/object.d(14)
> conflicts with my_printf.printf at my_printf.d(3)»

You've more or less answered your own question: use a fully-qualified name.  Alternatively, use in test.d

    alias my_printf.printf printf;

However, when doing it on functions with C linkage, you have to be careful.  Because they don't have the module name mangled in, you may cause a linker conflict or end up inadvertently calling the C library function with the same name.  Indeed, I don't know why this doesn't cause a linker conflict when I try it (under DMD 1.00, Win98SE).

Stewart.
January 12, 2007
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??
« First   ‹ Prev
1 2
Top | Discussion index | About this forum | D home