So I have this recurring pattern, it's really starting to annoy me.<div>It stems from the fact that a function prototype and the definition can not appear in the same file in D (as it can in C/C++)</div><div>Eg,</div><div>
<br></div><div>void func(int x); // <-- declaration of function, informs type and associated names, args, ...</div><div><br></div><div>//later</div><div>void func(int x) // <-- may be generated with magic (and may use the prototype declaration for type information as declared by the prototype above)</div>
<div>{</div><div> ... do stuff</div><div>}</div><div><br></div><div>I really need this. Why is it illegal? Is there chance of having this supported? What are the problems?</div><div><br></div><div>My problem is essentially to do with supporting both static or dynamic linkage optionally, but it also shows up in situations where I want to perform comprehensive magic code generation, but want clear-readable user declarations.</div>
<div>The simplest case:</div><div> I have an extern that I may want to statically or dynamically link.</div><div> In the case of static linkage, one just produces a prototype, and it links, no problem.</div><div> In the case of dynamic linkage, one must produce a stub for the function, a function pointer to call through, and perhaps some code to hook-up the function pointer at init.</div>
<div><br></div><div>I have a fairly comprehensive binding solution which automates the work in the case of dynamic linkage, but the problem is the way the user defines the functions that exist in the D code.</div><div>I'd like it if the users would just write the prototypes, they'd be easily readable, simple to create by cutting and pasting straight from C code. And when statically linking, it would just work, the module hook-up mixin does nothing in this configuration.</div>
<div>In the case of dynamic linkage, a single hook-up mixin in the file somewhere could scan the module for these prototypes and generate the stubs, function pointers, and the boot-up code that would connect them (while validating their signatures against the extern import table, etc).</div>
<div><br></div><div>This approach isn't supported though. What I do instead:</div><div><br></div><div>mixin( ImportFunction!( "functionName", int function( int arg1, float arg2, ref in SomeStruct arg3 ), "pure nothrow" ) );</div>
<div>mixin( ImportFunction!( "functionName2", int function() ) );
</div><div>mixin( ImportFunction!( "functionName3", int function( int x, int y ), "nothrow" ) );
</div><div>etc etc</div><div><br></div><div>These templates produce, from the information provided, either a prototype for static linkage, or the { stub, func pointer, initialisation info } for dynamic linkage.</div><div>
<br></div><div>I really don't like doing it this way for a number of reasons:</div><div> *** This results in hundreds of mixins, which quickly lead to intolerable compile times (to the point where D is losing it's appeal as a viable choice for our needs). If done my preferred way, I could do the magic with a single mixin at the bottom of the file.</div>
<div> * It's barely readable.</div><div> * Much more annoying to write and maintain when the counterpart API changes, and is more error-prone.</div><div> * IDE features don't work properly; syntax highlighting, hover info, go-to-definition, etc.</div>
<div><br></div><div>I also have numerous more advanced cases of the same problem, and becomes even more unsightly when used in structs to emulate dynamic linkage to static methods of C++ classes.</div><div><br></div><div>
The solution is seemingly trivial; allow function prototypes and definitions to exist in the same file, like in C/C++.</div><div><br></div><div><br></div><div>Go on, tear me apart... :)</div>