www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Error: WndProc - nothrow

reply "deed" <none none.none> writes:
I get this error from a minimal windows example:

import core.runtime;
import std.c.windows.windows;
import std.string;

pragma(lib, "gdi32.lib");

extern (Windows)
{
int WinMain( ... ) { ... }
HRESULT appMain( ... ) {
     ...
     WNDCLASS wc;
     ...
     wc.lpfnWndProc = &wndProc;
     ...
}
HRESULT wndProc( ... ) { ... }
}

Error: cannot implicitly convert expression (& wndProc) of type
extern (Windows) int function(void* hwnd, uint message, uint 
wParam, int lParam)
to
extern (Windows) int function(void*, uint, uint, int) nothrow
shell returned 1

What does the nothrow stems from? Is this something new?
Sep 16 2012
next sibling parent reply =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= <alex lycus.org> writes:
On 16-09-2012 19:39, deed wrote:
 I get this error from a minimal windows example:

 import core.runtime;
 import std.c.windows.windows;
 import std.string;

 pragma(lib, "gdi32.lib");

 extern (Windows)
 {
 int WinMain( ... ) { ... }
 HRESULT appMain( ... ) {
      ...
      WNDCLASS wc;
      ...
      wc.lpfnWndProc = &wndProc;
      ...
 }
 HRESULT wndProc( ... ) { ... }
 }

 Error: cannot implicitly convert expression (& wndProc) of type
 extern (Windows) int function(void* hwnd, uint message, uint wParam, int
 lParam)
 to
 extern (Windows) int function(void*, uint, uint, int) nothrow
 shell returned 1

 What does the nothrow stems from? Is this something new?
nothrow is a function attribute meaning "this function does not throw exceptions". Just mark your wndProc function as nothrow and it should go away. http://dlang.org/function.html#nothrow-functions -- Alex Rønne Petersen alex lycus.org http://lycus.org
Sep 16 2012
parent reply "deed" <none none.none> writes:
I did, but then I am not able to use writeln for debugging.
Is this restriction something new?
Sep 16 2012
next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
deed:

 I did, but then I am not able to use writeln for debugging.
writeln is a "throwing" function, so you can't use it inside a nothrow function.
 Is this restriction something new?
It's not new. I think writeln was always "throwing", since the creation of "nothrow". Bye, bearophile
Sep 16 2012
parent "deed" <none none.none> writes:
But why is the wndProc function nothrow?
Why do I have to mark it with nothrow?
Sep 16 2012
prev sibling parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Sunday, 16 September 2012 at 21:12:42 UTC, deed wrote:
 I did, but then I am not able to use writeln for debugging.
 Is this restriction something new?
nothrow just means the function itself should not *exit* with an exception. It is still legally allowed to call a throwing function, provided promises to handles (catche) any thrown exception. How it deals with the exception (silence/error) is up to it. For example: -------- void foo() nothrow { try { writeln("hello world!"); } catch(Exception) { } //silence //doStuff } -------- Of course, the "try catch do nothing" writting can get old, so you can use std.exception's "collectException" too*; -------- void foo() nothrow { collectException(writeln("hello world!")); //doStuff } -------- *Though for me, the compiler sometimes still complains. Or better yet, you *could* write a "debugWriteln()", which is marked as trusted nothrow: -------- trusted nothrow void debugWriteln(Args...)(Args args) nothrow { try{writeln(args);}catch(Exception){}; } void foo() nothrow { debugWriteln("hello world!"); //doStuff } -------- The trusted is so that it can also be used inside safe functions (which will exhibit the same issue). With this, you can log in any function.
Sep 16 2012
prev sibling parent reply "cal" <callumenator gmail.com> writes:
On Sunday, 16 September 2012 at 17:38:35 UTC, deed wrote:
 What does the nothrow stems from? Is this something new?
Isn't the real question why the wndProc function is expected to be nothrow? The change is from this commit 4 months ago: 2886846a92c45d92308756cf4c077ae13f0f8460
Sep 16 2012
next sibling parent reply "deed" <none none.none> writes:
Exactly. I couldn't remember seeing this error before.
Sep 16 2012
parent reply "cal" <callumenator gmail.com> writes:
On Sunday, 16 September 2012 at 22:08:53 UTC, deed wrote:
 Exactly. I couldn't remember seeing this error before.
I've only used the dsource Win32 bindings, because there is often stuff missing from the phobos ones: http://www.dsource.org/projects/bindings/wiki/WindowsApi But I don't understand the reason for the change to the phobos bindings. Like someone above said, the easiest solution is to wrap your wndProc body in a try/catch.
Sep 16 2012
parent reply Simon <s.d.hammett gmail.com> writes:
On 16/09/2012 23:32, cal wrote:
 On Sunday, 16 September 2012 at 22:08:53 UTC, deed wrote:
 Exactly. I couldn't remember seeing this error before.
I've only used the dsource Win32 bindings, because there is often stuff missing from the phobos ones: http://www.dsource.org/projects/bindings/wiki/WindowsApi But I don't understand the reason for the change to the phobos bindings. Like someone above said, the easiest solution is to wrap your wndProc body in a try/catch.
A window proc is being called directly by Win32 which expects that the wndproc is a strict C function. You MUST NOT allow a D exception to propagate out of the wndproc (or indeed any other Win32 callback function) as the Win32 calling code has no idea how to process it and you'll just get a crash. Also the crash address that you get will be in a windows system dll which will just confuse matters when you try and debug the problem. So yes, the correct thing to do is wrap all D code in try catch block. -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk
Sep 17 2012
parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 9/17/12, Simon <s.d.hammett gmail.com> wrote:
 You MUST NOT allow a D exception to
 propagate out of the wndproc (or indeed any other Win32 callback
 function) as the Win32 calling code has no idea how to process it and
 you'll just get a crash.
That's just complete and utter bullshit. A try/catch can be set in WinMain, and any thrown exceptions in WndProc will propagate there. Code: http://dpaste.dzfl.pl/84293982 Screenshot: http://i.imgur.com/r5wJh.png
Sep 17 2012
parent reply Simon <s.d.hammett gmail.com> writes:
On 17/09/2012 23:13, Andrej Mitrovic wrote:
 On 9/17/12, Simon <s.d.hammett gmail.com> wrote:
 You MUST NOT allow a D exception to
 propagate out of the wndproc (or indeed any other Win32 callback
 function) as the Win32 calling code has no idea how to process it and
 you'll just get a crash.
That's just complete and utter bullshit. A try/catch can be set in WinMain, and any thrown exceptions in WndProc will propagate there. Code: http://dpaste.dzfl.pl/84293982 Screenshot: http://i.imgur.com/r5wJh.png
Hmm, didn't work for me when I ported the Atl windowing stuff. And it doesn't work in VC++. Have they changed D exception mechanism to use Structured exception handling? -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk
Sep 18 2012
parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 9/18/12, Simon <s.d.hammett gmail.com> wrote:
 That's just complete and utter bullshit. A try/catch can be set in
 WinMain, and any thrown exceptions in WndProc will propagate there.

 Code:
 http://dpaste.dzfl.pl/84293982

 Screenshot:
 http://i.imgur.com/r5wJh.png
Hmm, didn't work for me when I ported the Atl windowing stuff. And it doesn't work in VC++. Have they changed D exception mechanism to use Structured exception handling?
I think Don has been busy doing that. MSDN says the exceptions are passed to "higher-level handlers": http://msdn.microsoft.com/en-us/library/windows/desktop/ms633573%28v=vs.85%29.aspx I did have to compile with -g and run the .exe through cv2pdb before the stacktrace printed proper files and lines. Also sorry for my harsh words I was in a bad mood yesterday. :)
Sep 18 2012
parent reply Simon <s.d.hammett gmail.com> writes:
On 18/09/2012 18:47, Andrej Mitrovic wrote:
 On 9/18/12, Simon <s.d.hammett gmail.com> wrote:
 That's just complete and utter bullshit. A try/catch can be set in
 WinMain, and any thrown exceptions in WndProc will propagate there.

 Code:
 http://dpaste.dzfl.pl/84293982

 Screenshot:
 http://i.imgur.com/r5wJh.png
Hmm, didn't work for me when I ported the Atl windowing stuff. And it doesn't work in VC++. Have they changed D exception mechanism to use Structured exception handling?
I think Don has been busy doing that. MSDN says the exceptions are passed to "higher-level handlers": http://msdn.microsoft.com/en-us/library/windows/desktop/ms633573%28v=vs.85%29.aspx I did have to compile with -g and run the .exe through cv2pdb before the stacktrace printed proper files and lines. Also sorry for my harsh words I was in a bad mood yesterday. :)
No worries; I'm sure that the main reason (apart from pron) why the internet is so popular is just for people to vent their spleen! I've just gone though my ATL port and taken out the special exception handling I had in and it just works. It's even got a full stack backtrace, w/ DMD 2.058 :) Cool. I never did like that special handling. Though to go back to the OPs question then, that nothrow attribute is clearly erogenous now. Mind you I've never used the phobos provided win32 bindings as they were pants. -- My enormous talent is exceeded only by my outrageous laziness. http://www.ssTk.co.uk
Sep 18 2012
parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 9/18/12, Simon <s.d.hammett gmail.com> wrote:
 No worries; I'm sure that the main reason (apart from pron)
Why, I've not a clue what you speaketh of!
 Though to go back to the OPs question then, that nothrow attribute is
 clearly erogenous now.
Also I would assume that adding a try/catch in every wndproc would slow down the message pump. Maybe not by much but that function is called often enough to matter.
 Mind you I've never used the phobos provided
 win32 bindings as they were pants.
They are pants, these are better: http://www.dsource.org/projects/bindings/wiki/WindowsApi I used them for: https://github.com/AndrejMitrovic/DWinProgramming
Sep 18 2012
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 9/17/12, cal <callumenator gmail.com> wrote:
 On Sunday, 16 September 2012 at 17:38:35 UTC, deed wrote:
 What does the nothrow stems from? Is this something new?
The change is from this commit 4 months ago: 2886846a92c45d92308756cf4c077ae13f0f8460
https://github.com/D-Programming-Language/druntime/pull/225 I don't understand this whole deal, what is or isn't allowed to be catched..
Sep 16 2012