View mode: basic / threaded / horizontal-split · Log in · Help
January 12, 2007
How to create a function declaration?
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
Re: How to create a function declaration?
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
Re: How to create a function declaration?
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
Re: How to create a function declaration?
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
Re: How to create a function declaration?
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
Re: How to create a function declaration?
> 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
Re: How to create a function declaration?
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
Re: How to create a function declaration?
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
Re: How to create a function declaration?
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
Re: How to create a function declaration?
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