www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Forward declaration inside Function block, no error?

reply Benjamin Thaut <code benjamin-thaut.de> writes:
Today I found a bug in my D code.


import std.stdio;

// Type your code here, or load an example.
void grow()
{
     writeln("grow");
}

void someFunc(bool condition)
{
     if(condition)
     {
         void grow();
     }
}


I tried to call the grow function, but accidentially copied the 
return value alongside the function name. I was wondering why 
this code compiles without errors. the "void grow();" becomes a 
no-op. In my opinion this could should not compile. Am I missing 
something here?

Kind Regards
Benjamin Thaut
Jan 06 2019
next sibling parent reply Rubn <where is.this> writes:
On Sunday, 6 January 2019 at 18:38:44 UTC, Benjamin Thaut wrote:
 Today I found a bug in my D code.


 import std.stdio;

 // Type your code here, or load an example.
 void grow()
 {
     writeln("grow");
 }

 void someFunc(bool condition)
 {
     if(condition)
     {
         void grow();
     }
 }


 I tried to call the grow function, but accidentially copied the 
 return value alongside the function name. I was wondering why 
 this code compiles without errors. the "void grow();" becomes a 
 no-op. In my opinion this could should not compile. Am I 
 missing something here?

 Kind Regards
 Benjamin Thaut
import std.stdio; void grow() { writeln("grow"); } void someFunc(bool condition) { if(condition) { void grow(); pragma(msg, grow.mangleof); // _D3app8someFuncFbZ4growMFZv } } You can declare functions inside of functions in D. You weren't forward declare grow() in the module namespace, so much as you were forward declaring a new function grow.
Jan 06 2019
parent Neia Neutuladh <neia ikeran.org> writes:
On Sun, 06 Jan 2019 20:19:59 +0000, Rubn wrote:
 You can declare functions inside of functions in D. You weren't forward
 declare grow() in the module namespace, so much as you were forward
 declaring a new function grow.
Unfortunately, you can't do forward declarations for nested functions. If you could, that would be handy for mutual recursion: void main() { int a(int i); int b(int i) { if (i > 0) return a(i - 1); return abs(i); } int a(int i) { if (i % 2 == 0) return b(i - 2); return b(i - 1); } writeln(a(12)); } Unfortunately, Error: declaration a is already defined And omitting the forward declaration gets you: Error: undefined identifier a
Jan 06 2019
prev sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Sunday, January 6, 2019 11:38:44 AM MST Benjamin Thaut via Digitalmars-d-
learn wrote:
 Today I found a bug in my D code.


 import std.stdio;

 // Type your code here, or load an example.
 void grow()
 {
      writeln("grow");
 }

 void someFunc(bool condition)
 {
      if(condition)
      {
          void grow();
      }
 }


 I tried to call the grow function, but accidentially copied the
 return value alongside the function name. I was wondering why
 this code compiles without errors. the "void grow();" becomes a
 no-op. In my opinion this could should not compile. Am I missing
 something here?
It would actually be useful if you could provide prototypes for extern(C) functions that way (similar to how we can have local imports for modules and thus avoid affecting the rest of the module), but unfortunately, that doesn't currently work (even if the function declaration is marked with static). It would also make sense if it allowed you to provide forward declarations for nested functions, but that doesn't work either. So, I could see uses cases where it would theoretically be useful to be able to declare function prototypes inside of a function, but as it stands, AFAIK, it's useless. It is arguably a case of "turtles all the way down," but since you can't then do anything useful with the function prototype, it's currently pretty pointless. - Jonathan M Davis
Jan 06 2019
parent Steven Schveighoffer <schveiguy gmail.com> writes:
On 1/7/19 12:20 AM, Jonathan M Davis wrote:
 On Sunday, January 6, 2019 11:38:44 AM MST Benjamin Thaut via Digitalmars-d-
 learn wrote:
 Today I found a bug in my D code.


 import std.stdio;

 // Type your code here, or load an example.
 void grow()
 {
       writeln("grow");
 }

 void someFunc(bool condition)
 {
       if(condition)
       {
           void grow();
       }
 }


 I tried to call the grow function, but accidentially copied the
 return value alongside the function name. I was wondering why
 this code compiles without errors. the "void grow();" becomes a
 no-op. In my opinion this could should not compile. Am I missing
 something here?
It would actually be useful if you could provide prototypes for extern(C) functions that way (similar to how we can have local imports for modules and thus avoid affecting the rest of the module), but unfortunately, that doesn't currently work (even if the function declaration is marked with static). It would also make sense if it allowed you to provide forward declarations for nested functions, but that doesn't work either. So, I could see uses cases where it would theoretically be useful to be able to declare function prototypes inside of a function, but as it stands, AFAIK, it's useless. It is arguably a case of "turtles all the way down," but since you can't then do anything useful with the function prototype, it's currently pretty pointless.
One could use it as a strawman, that's never called, but used for introspection. I tried to use pragma(mangle), but it doesn't seem to work on inner functions (weird). If I declare the pragma(mangle) outside the function, it works, but that doesn't help if the function actually needs the outer function context to operate. Allowing forward declarations for nested functions would be nice. -Steve
Jan 07 2019