www.digitalmars.com         C & C++   DMDScript  

D - nested function problems

reply "Dario" <supdar yahoo.com> writes:
    void function() fp;
    extern(Windows) int func()
    {
        static int otherfunc()
        { return 0; }

        fp = &otherfunc;
        return fp();
    }

This code won't work since function otherfunc is extern(Windows).
I have no way to declare it extern(D). I can't even write the word
'extern' inside a function body.
I think that nested functions shouldn't follow their enclosing function
calling convention. They should be extern(D) by default.
And we should be able to specify the convention to use with the
'extern' keyword also inside other functions' body (both for functions
and for function pointers).

I also noticed that we have to write the nested function before using it.
I think this is incongruous with the general rule: D must care not where
a function is written, but only if it's written in the correct scope.
The same rule should apply to imports. (Actually the import statement
must precede the code that uses the imported symbols.)

I'd also like very much to be allowed to import a module in a function,
see the example:
int main()
{
    import ctype;
    return isalpha("5");
}
I remember I already asked for this feature but it was rejected.
I don't remeber why...
May 14 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Dario" <supdar yahoo.com> wrote in message
news:b9th87$1aop$1 digitaldaemon.com...
     void function() fp;
     extern(Windows) int func()
     {
         static int otherfunc()
         { return 0; }

         fp = &otherfunc;
         return fp();
     }

 This code won't work since function otherfunc is extern(Windows).
 I have no way to declare it extern(D). I can't even write the word
 'extern' inside a function body.
 I think that nested functions shouldn't follow their enclosing function
 calling convention. They should be extern(D) by default.
You're right.
 And we should be able to specify the convention to use with the
 'extern' keyword also inside other functions' body (both for functions
 and for function pointers).
I'm less sure of that. The reason to specify the calling conventions is to be compatible with non-D functions. Nested functions are always D functions.
 I also noticed that we have to write the nested function before using it.
That's true of all declarations within a function.
 I think this is incongruous with the general rule: D must care not where
 a function is written, but only if it's written in the correct scope.
I think you're right, but it's a significant impact on the semantic analyzer.
 The same rule should apply to imports. (Actually the import statement
 must precede the code that uses the imported symbols.)

 I'd also like very much to be allowed to import a module in a function,
 see the example:
 int main()
 {
     import ctype;
     return isalpha("5");
 }
 I remember I already asked for this feature but it was rejected.
 I don't remeber why...
I don't remember why, either <g>.
May 14 2003
next sibling parent reply "Sean L. Palmer" <palmer.sean verizon.net> writes:
What is so hard about allowing extern declarators wherever an interface
declaration is allowed?  Why must there be a special case?  At least allow
us to specify an extern type if we wish to.  Defaulting to D linkage is good
in that case.  But the ability to override seems necessary.

What is this semantic problem?

Sean

"Walter" <walter digitalmars.com> wrote in message
news:b9v4uu$1gq$2 digitaldaemon.com...
 "Dario" <supdar yahoo.com> wrote in message
 news:b9th87$1aop$1 digitaldaemon.com...
     void function() fp;
     extern(Windows) int func()
     {
         static int otherfunc()
         { return 0; }

         fp = &otherfunc;
         return fp();
     }

 This code won't work since function otherfunc is extern(Windows).
 I have no way to declare it extern(D). I can't even write the word
 'extern' inside a function body.
 I think that nested functions shouldn't follow their enclosing function
 calling convention. They should be extern(D) by default.
You're right.
 And we should be able to specify the convention to use with the
 'extern' keyword also inside other functions' body (both for functions
 and for function pointers).
I'm less sure of that. The reason to specify the calling conventions is to be compatible with non-D functions. Nested functions are always D
functions.
 I also noticed that we have to write the nested function before using
it.
 That's true of all declarations within a function.

 I think this is incongruous with the general rule: D must care not where
 a function is written, but only if it's written in the correct scope.
I think you're right, but it's a significant impact on the semantic analyzer.
 The same rule should apply to imports. (Actually the import statement
 must precede the code that uses the imported symbols.)

 I'd also like very much to be allowed to import a module in a function,
 see the example:
 int main()
 {
     import ctype;
     return isalpha("5");
 }
 I remember I already asked for this feature but it was rejected.
 I don't remeber why...
I don't remember why, either <g>.
May 14 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Sean L. Palmer" <palmer.sean verizon.net> wrote in message
news:b9v8el$4m3$1 digitaldaemon.com...
 What is so hard about allowing extern declarators wherever an interface
 declaration is allowed?  Why must there be a special case?  At least allow
 us to specify an extern type if we wish to.  Defaulting to D linkage is
good
 in that case.  But the ability to override seems necessary.
Why is it necessary? The only purpose for the extern is to interface with functions written in other languages. Those languages do not support calling nested functions.
 What is this semantic problem?
Function semantic processing is done in one pass, whereas the global is done in 3 passes.
May 20 2003
parent reply "Matthew Wilson" <matthew stlsoft.org> writes:
 Why is it necessary? The only purpose for the extern is to interface with
 functions written in other languages. Those languages do not support
calling
 nested functions.
What about the ability to pass nested functions as callbacks to other functions. This is a C++ function I wrote that is effectively GetDlgItem() for n-level children HWND FindChildById(HWND hwndParent, int const id) { if(::GetDlgCtrlID(hwndParent) == id) { return hwndParent; } else { class ChildFind { public: explicit ChildFind(HWND hwndParent, int const id) : m_hwndChild(NULL) , m_id(id) { ::EnumChildWindows( hwndParent, EnumProc, reinterpret_cast<LPARAM>(this)); } public: operator HWND() const { return m_hwndChild; } private: static BOOL CALLBACK EnumProc(HWND hwnd, LPARAM lParam) { ChildFind &find = *reinterpret_cast<ChildFind*>(lParam); return (::GetDlgCtrlID(hwnd) == find.m_id) ? (find.m_hwndChild = hwnd, FALSE) : TRUE; } private: HWND m_hwndChild; int const m_id; } find(hwndParent, id); return find; } } It uses a nested class in order to get the callback. It would be very nice to be able to do similar things with nested functions, no? The D implementation could be something like HWND FindChildById(HWND hwndParent, int id) { if(GetDlgCtrlID(hwndParent) == id) { return hwndParent; } else { class ChildFind { HWND hwndChild; int const id; }; ChildFind cf; cf.hwndChild = NULL; cf.id = id; extern(Windows) BOOL FindChildProc(HWND hwnd, LPARAM lParam) { ChildFind find = *reinterpret_cast<ChildFind*>(lParam); return (GetDlgCtrlID(hwnd) == find.m_id) ? (find.m_hwndChild = hwnd, FALSE) : TRUE; } ::EnumChildWindows(hwndParent, FindChildProc, reinterpret_cast<LPARAM>(&cf)); return cf.hwndChild; } } which is even more succinct. (btw, this is not compiled, so may not be syntactically correct)
May 21 2003
parent reply "Walter" <walter digitalmars.com> writes:
It would be nice, but Windows doesn't know how to call nested functions. If
you're using it with other D functions, there's no need to give it a Windows
calling convention.
May 27 2003
parent reply "Matthew Wilson" <matthew stlsoft.org> writes:
Sorry, I don't grok your answer.

Surely D works with windows callbacks? All I'm saying is to allow them
inside D functions.

"Walter" <walter digitalmars.com> wrote in message
news:bb1ghc$2j50$1 digitaldaemon.com...
 It would be nice, but Windows doesn't know how to call nested functions.
If
 you're using it with other D functions, there's no need to give it a
Windows
 calling convention.
May 28 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Matthew Wilson" <matthew stlsoft.org> wrote in message
news:bb38fa$1g7q$1 digitaldaemon.com...
 Sorry, I don't grok your answer.

 Surely D works with windows callbacks? All I'm saying is to allow them
 inside D functions.
D does work with windows callbacks. But the callbacks need to be module level functions, not nested functions. Windows does not support D nested functions.
 "Walter" <walter digitalmars.com> wrote in message
 news:bb1ghc$2j50$1 digitaldaemon.com...
 It would be nice, but Windows doesn't know how to call nested functions.
If
 you're using it with other D functions, there's no need to give it a
Windows
 calling convention.
Jun 27 2003
next sibling parent reply "Matthew Wilson" <matthew stlsoft.org> writes:
Alas, the brain is weak, and I still don't get it. Nor do I understand what
"Windows does not support D nested functions" means. Isn't this the wrong
way round?

"Walter" <walter digitalmars.com> wrote in message
news:bdie99$139m$2 digitaldaemon.com...
 "Matthew Wilson" <matthew stlsoft.org> wrote in message
 news:bb38fa$1g7q$1 digitaldaemon.com...
 Sorry, I don't grok your answer.

 Surely D works with windows callbacks? All I'm saying is to allow them
 inside D functions.
D does work with windows callbacks. But the callbacks need to be module level functions, not nested functions. Windows does not support D nested functions.
 "Walter" <walter digitalmars.com> wrote in message
 news:bb1ghc$2j50$1 digitaldaemon.com...
 It would be nice, but Windows doesn't know how to call nested
functions.
 If
 you're using it with other D functions, there's no need to give it a
Windows
 calling convention.
Jul 08 2003
parent reply "Julio César Carrascal Urquijo" <adnoctum phreaker.net> writes:
"Matthew Wilson" <matthew stlsoft.org> wrote in message
news:befroh$16hq$1 digitaldaemon.com...
 Alas, the brain is weak, and I still don't get it. Nor do I understand
what
 "Windows does not support D nested functions" means. Isn't this the wrong
 way round?
I think it's the same reason why Windows (or C linkers, really) doesn't support D class methods: They need an extra pointer to the enclosing scope. _____________________________ Julio César Carrascal Urquijo <adnoctum_at_phreaker_dot_net>
Jul 09 2003
parent reply "Matthew Wilson" <matthew stlsoft.org> writes:
I never said I wanted them to be class methods. Just nested functions.

"Julio César Carrascal Urquijo" <adnoctum phreaker.net> wrote in message
news:behdgl$2l2k$1 digitaldaemon.com...
 "Matthew Wilson" <matthew stlsoft.org> wrote in message
 news:befroh$16hq$1 digitaldaemon.com...
 Alas, the brain is weak, and I still don't get it. Nor do I understand
what
 "Windows does not support D nested functions" means. Isn't this the
wrong
 way round?
I think it's the same reason why Windows (or C linkers, really) doesn't support D class methods: They need an extra pointer to the enclosing
scope.
 _____________________________

 Julio César Carrascal Urquijo
 <adnoctum_at_phreaker_dot_net>
Jul 09 2003
parent reply Ilya Minkov <midiclub 8ung.at> writes:
Matthew Wilson wrote:
 I never said I wanted them to be class methods. Just nested functions.
Nested functions get access to the local variables in the parent functions as if they were globals. To accomplish that, they get a hidden parameter -- pointer to a previous stack frame. This feature requieres a special compiler support, and is thus not callable from C, Pascal, or whatever other compiled language. Not even the same language outside the scope of the function where it was defined - because it would inevatably break, since variable ordering is only known to compiler when it compiles a specific function. This hidden-pointer-thingy is somewhat similar in concept to the class functions, though class functions must be simpler to workaround, since field ordering in a class can be reconstructed from its formal description, unlike the local variable order. Tell me what you need nested functions with other calling conventions for? -i.
Jul 09 2003
parent "Matthew Wilson" <matthew stlsoft.org> writes:
See my post of the 22nd May

"Ilya Minkov" <midiclub 8ung.at> wrote in message
news:bei20l$92j$1 digitaldaemon.com...
 Matthew Wilson wrote:
 I never said I wanted them to be class methods. Just nested functions.
Nested functions get access to the local variables in the parent functions as if they were globals. To accomplish that, they get a hidden parameter -- pointer to a previous stack frame. This feature requieres a special compiler support, and is thus not callable from C, Pascal, or whatever other compiled language. Not even the same language outside the scope of the function where it was defined - because it would inevatably break, since variable ordering is only known to compiler when it compiles a specific function. This hidden-pointer-thingy is somewhat similar in concept to the class functions, though class functions must be simpler to workaround, since field ordering in a class can be reconstructed from its formal description, unlike the local variable order. Tell me what you need nested functions with other calling conventions for? -i.
Jul 09 2003
prev sibling parent reply Antti =?iso-8859-1?Q?Syk=E4ri?= <jsykari gamma.hut.fi> writes:
In article <bdie99$139m$2 digitaldaemon.com>, Walter wrote:
 
 "Matthew Wilson" <matthew stlsoft.org> wrote in message
 news:bb38fa$1g7q$1 digitaldaemon.com...
 Sorry, I don't grok your answer.

 Surely D works with windows callbacks? All I'm saying is to allow them
 inside D functions.
D does work with windows callbacks. But the callbacks need to be module level functions, not nested functions. Windows does not support D nested functions.
How about static nested functions, then? AFAIK, they're just ordinary functions, only defined in a function scope, and could as well be called by Windows. -Antti
Jul 09 2003
next sibling parent "Matthew Wilson" <matthew stlsoft.org> writes:
Exactly. That is what I want.

See post of 22nd May for a good example of why this is desirable

"Antti Sykäri" <jsykari gamma.hut.fi> wrote in message
news:slrnbgp9gq.q7q.jsykari seth.hut.fi...
 In article <bdie99$139m$2 digitaldaemon.com>, Walter wrote:
 "Matthew Wilson" <matthew stlsoft.org> wrote in message
 news:bb38fa$1g7q$1 digitaldaemon.com...
 Sorry, I don't grok your answer.

 Surely D works with windows callbacks? All I'm saying is to allow them
 inside D functions.
D does work with windows callbacks. But the callbacks need to be module level functions, not nested functions. Windows does not support D nested functions.
How about static nested functions, then? AFAIK, they're just ordinary functions, only defined in a function scope, and could as well be called by Windows. -Antti
Jul 09 2003
prev sibling parent reply "Sean L. Palmer" <palmer.sean verizon.net> writes:
That might be ok.

How's this:  If a nested function is declared with a D calling convention,
it has access to the containing function stack frame, otherwise it doesn't.

That way you could declare Windows callbacks locally, although they don't
have the same benefits as making other D functions nested, it could be
convenient and it avoids polluting the module namespace.

Sean

"Antti Sykäri" <jsykari gamma.hut.fi> wrote in message
news:slrnbgp9gq.q7q.jsykari seth.hut.fi...
 In article <bdie99$139m$2 digitaldaemon.com>, Walter wrote:
 "Matthew Wilson" <matthew stlsoft.org> wrote in message
 news:bb38fa$1g7q$1 digitaldaemon.com...
 Sorry, I don't grok your answer.

 Surely D works with windows callbacks? All I'm saying is to allow them
 inside D functions.
D does work with windows callbacks. But the callbacks need to be module level functions, not nested functions. Windows does not support D nested functions.
How about static nested functions, then? AFAIK, they're just ordinary functions, only defined in a function scope, and could as well be called by Windows. -Antti
Jul 10 2003
parent "Matthew Wilson" <matthew stlsoft.org> writes:
Exactly what I want, and perfectly expressed.

Thanks Sean

:)

"Sean L. Palmer" <palmer.sean verizon.net> wrote in message
news:bek51e$28m7$1 digitaldaemon.com...
 That might be ok.

 How's this:  If a nested function is declared with a D calling convention,
 it has access to the containing function stack frame, otherwise it
doesn't.
 That way you could declare Windows callbacks locally, although they don't
 have the same benefits as making other D functions nested, it could be
 convenient and it avoids polluting the module namespace.

 Sean

 "Antti Sykäri" <jsykari gamma.hut.fi> wrote in message
 news:slrnbgp9gq.q7q.jsykari seth.hut.fi...
 In article <bdie99$139m$2 digitaldaemon.com>, Walter wrote:
 "Matthew Wilson" <matthew stlsoft.org> wrote in message
 news:bb38fa$1g7q$1 digitaldaemon.com...
 Sorry, I don't grok your answer.

 Surely D works with windows callbacks? All I'm saying is to allow
them
 inside D functions.
D does work with windows callbacks. But the callbacks need to be
module
 level functions, not nested functions. Windows does not support D
nested
 functions.
How about static nested functions, then? AFAIK, they're just ordinary functions, only defined in a function
scope,
 and could as well be called by Windows.

 -Antti
Jul 10 2003
prev sibling next sibling parent reply "Dario" <supdar yahoo.com> writes:
 And we should be able to specify the convention to use with the
 'extern' keyword also inside other functions' body (both for functions
 and for function pointers).
I'm less sure of that. The reason to specify the calling conventions is to be compatible with non-D functions. Nested functions are always D
functions. But static nested functions don't have to be D functions. Moreover, how to write a pointer to a Windows function? void func() { extern(Windows) void function() a; } (this code doesn't compile.)
 I also noticed that we have to write the nested function before using
it.
 That's true of all declarations within a function.
I agree that data declaration must precede the code that uses it. But I think function declaration shouldn't.
 I think this is incongruous with the general rule: D must care not where
 a function is written, but only if it's written in the correct scope.
I think you're right, but it's a significant impact on the semantic analyzer.
I suspected it. <='( We can live without it, but it's sometimes boring.
 The same rule should apply to imports. (Actually the import statement
 must precede the code that uses the imported symbols.)

 I'd also like very much to be allowed to import a module in a function,
 see the example:
 int main()
 {
     import ctype;
     return isalpha("5");
 }
 I remember I already asked for this feature but it was rejected.
 I don't remeber why...
I don't remember why, either <g>.
I think it was because of the phases of the compilation process. Or maybe I'm simply misremembering... ;-) Can it be done?
May 15 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Dario" <supdar yahoo.com> wrote in message
news:ba066a$1237$1 digitaldaemon.com...
 And we should be able to specify the convention to use with the
 'extern' keyword also inside other functions' body (both for functions
 and for function pointers).
I'm less sure of that. The reason to specify the calling conventions is
to
 be compatible with non-D functions. Nested functions are always D
functions. But static nested functions don't have to be D functions. Moreover, how to write a pointer to a Windows function? void func() { extern(Windows) void function() a; } (this code doesn't compile.)
Since Windows has no concept of nested D functions, it can't set up the frame properly for it. Nested functions are not supported by C, and so cannot be supported by external C code.
May 20 2003
parent reply "Dario" <supdar yahoo.com> writes:
 Moreover, how to write a pointer to a Windows function?
     void func()
     {
         extern(Windows) void function() a;
     }
 (this code doesn't compile.)
 Since Windows has no concept of nested D functions, it can't set up the
 frame properly for it. Nested functions are not supported by C, and so
 cannot be supported by external C code.
Consider this code: void createwndclass() { extern(Windows) static int wndproc(HWND w, int m, WPARAM w, LPARAM l) { switch(m) {...} } WNDCLASS wndclass = { lpfnWndProc: &wndproc, ... }; RegisterClass(&wndclass); } Shouldn't this be correct? Why shouldn't a static nested function be extern(Windows)?
May 21 2003
parent "Walter" <walter digitalmars.com> writes:
You're right that a static nested function could be (Windows), since it has
no enclosing frame pointer.
May 27 2003
prev sibling parent reply "Dario" <supdar yahoo.com> writes:
 I also noticed that we have to write the nested function before using
it.
 I think this is incongruous with the general rule: D must care not where
 a function is written, but only if it's written in the correct scope.
 I think you're right, but it's a significant impact on the semantic
 analyzer.
I found out that this restriction prevents two nested functions call one another. void func() { void one() { two(); // error: two is not declared yet } void two() { one(); // ok } } So the work-around of moving the nested functions before they're used does not always work.
May 21 2003
parent "Walter" <walter digitalmars.com> writes:
"Dario" <supdar yahoo.com> wrote in message
news:baghm5$2u3b$2 digitaldaemon.com...
 I found out that this restriction prevents two nested functions call one
 another.
     void func()
     {
         void one()
         {
             two(); // error: two is not declared yet
         }
         void two()
         {
             one(); // ok
         }
     }
 So the work-around of moving the nested functions before they're used
 does not always work.
You're correct.
May 27 2003