www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - This shouldn't happen

reply "Mehrdad" <wfunction hotmail.com> writes:
There's an access violation when you run this. See if you can figure out the
error.

Guess what the cause is?
HINT: It would've been a 2-second fix instead of a 300-second fix, if D
hadn't been so shortsighted and hadn't removed typedef's...

import win32.windows;
void main() {
    auto hwnd = CreateWindow("STATIC", "Hi!", WS_OVERLAPPEDWINDOW |
WS_VISIBLE, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
null, null, null, null);
    BOOL bRet;
    MSG msg;
    while ((bRet = GetMessage(null, &msg, 0, 0)) != 0) {
        if (bRet == -1) { break; }
        else {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
} 
Apr 25 2012
next sibling parent reply "bearophile" <bearophileHUGS lycos.com> writes:
Mehrdad:

 if D
 hadn't been so shortsighted and hadn't removed typedef's...

Now there's std.typecons.Typedef, but of course it's not usable for real: http://d.puremagic.com/issues/show_bug.cgi?id=7737 http://d.puremagic.com/issues/show_bug.cgi?id=7738 http://d.puremagic.com/issues/show_bug.cgi?id=7255 Bye, bearophile
Apr 25 2012
next sibling parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 4/25/12 1:05 PM, Andrej Mitrovic wrote:
 On 4/25/12, bearophile<bearophileHUGS lycos.com>  wrote:
 Mehrdad:

 if D
 hadn't been so shortsighted and hadn't removed typedef's...

Now there's std.typecons.Typedef

Right, but the error messages will be awful, e.g.: struct None { } alias Typedef!None HWND;

You need Typedef!(None*). Andrei
Apr 25 2012
prev sibling parent Stewart Gordon <smjg_1998 yahoo.com> writes:
On 25/04/2012 21:28, Andrej Mitrovic wrote:
<snip>
 This works well I think:
 struct HWND { }

If it does, it shouldn't, because that struct is of the wrong size. Windows handles are, AIUI, always of the platform pointer size. A zero-size handle type would be useless, as only one distinct handle could exist that way. Stewart.
Apr 28 2012
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 4/25/12, bearophile <bearophileHUGS lycos.com> wrote:
 Mehrdad:

 if D
 hadn't been so shortsighted and hadn't removed typedef's...

Now there's std.typecons.Typedef

Right, but the error messages will be awful, e.g.: struct None { } alias Typedef!None HWND; void test(HWND a, void* b) { } void main() { test(null, null); } test.d(24): Error: function test.test (Typedef!(None,None()) a, void* b) is not callable using argument types (typeof(null),typeof(null)) We can't just use Typedef!(void*) or Typedef!(int) because -=/+= will be allowed, which shouldn't be allowed for handles. const(void*) won't work either, because you should be allowed to assign one handle to another and const forbids that.
Apr 25 2012
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Andrej Mitrovic:

 Right, but the error messages will be awful, e.g.:

 struct None { }
 alias Typedef!None HWND;

 void test(HWND a, void* b) { }
 void main()
 {
     test(null, null);
 }

 test.d(24): Error: function test.test (Typedef!(None,None()) a, 
 void*
 b) is not callable using argument types 
 (typeof(null),typeof(null))

In this case what error message would you like to receive?
 We can't just use Typedef!(void*) or Typedef!(int) because 
 -=/+= will
 be allowed, which shouldn't be allowed for handles. 
 const(void*) won't
 work either, because you should be allowed to assign one handle 
 to
 another and const forbids that.

What about creating a Handle struct with your desired semantics? Bye, bearophile
Apr 25 2012
prev sibling next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 4/25/12, bearophile <bearophileHUGS lycos.com> wrote:
 In this case what error message would you like to receive?

The alias itself. HWND, not Typedef!(void*). But this isn't specific to Typedef, it's specific to how error messages are written.
 What about creating a Handle struct with your desired semantics?

This works well I think: struct HWND { }
Apr 25 2012
parent "Nick Sabalausky" <SeeWebsiteToContactMe semitwist.com> writes:
"Andrej Mitrovic" <andrej.mitrovich gmail.com> wrote in message 
news:mailman.2129.1335385811.4860.digitalmars-d puremagic.com...
 On 4/25/12, bearophile <bearophileHUGS lycos.com> wrote:
 In this case what error message would you like to receive?

The alias itself. HWND, not Typedef!(void*).

I've long been convinced that unaliasing symbols for DMD's output messages is a big, big mistake. It's nearly always the wrong level of abstraction.
Apr 25 2012
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 4/25/12, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:
 This works well I think:
 struct HWND { }

I'll eat my own words. It needs more work than that. E.g. this has to work: const HANDLE INVALID_HANDLE_VALUE = cast(HANDLE) (-1);
Apr 25 2012
prev sibling next sibling parent reply "H. S. Teoh" <hsteoh quickfur.ath.cx> writes:
On Thu, Apr 26, 2012 at 12:43:00AM -0400, Nick Sabalausky wrote:
 "Andrej Mitrovic" <andrej.mitrovich gmail.com> wrote in message 
 news:mailman.2129.1335385811.4860.digitalmars-d puremagic.com...
 On 4/25/12, bearophile <bearophileHUGS lycos.com> wrote:
 In this case what error message would you like to receive?

The alias itself. HWND, not Typedef!(void*).

I've long been convinced that unaliasing symbols for DMD's output messages is a big, big mistake. It's nearly always the wrong level of abstraction.

Why can't we have both? Sometimes you *want* to know what's hiding behind that alias, esp. when debugging deeply nested generic code where this is far from obvious. For example, given this C++ code: typedef int* CSPTR; int main() { CSPTR p = "abc"; } g++ 4.6.3 gives this message: /tmp/test.c: In function ‘int main()’: /tmp/test.c:3:12: error: cannot convert ‘const char*’ to ‘CSPTR {aka int*}’ in initialization Both the typedef name and the actual type are specified in the message, which makes it eminently useful in both the case where you're expecting the typedef'd name and the case where you want to know what's behind it. I say dmd should do the same thing. There's no reason to only print one over the other when you can just print both. Full disclosure is the best policy when there's a problem. T -- Democracy: The triumph of popularity over principle. -- C.Bond
Apr 25 2012
parent "Nick Sabalausky" <SeeWebsiteToContactMe semitwist.com> writes:
"H. S. Teoh" <hsteoh quickfur.ath.cx> wrote in message 
news:mailman.2145.1335417218.4860.digitalmars-d puremagic.com...
 On Thu, Apr 26, 2012 at 12:43:00AM -0400, Nick Sabalausky wrote:
 "Andrej Mitrovic" <andrej.mitrovich gmail.com> wrote in message
 news:mailman.2129.1335385811.4860.digitalmars-d puremagic.com...
 On 4/25/12, bearophile <bearophileHUGS lycos.com> wrote:
 In this case what error message would you like to receive?

The alias itself. HWND, not Typedef!(void*).

I've long been convinced that unaliasing symbols for DMD's output messages is a big, big mistake. It's nearly always the wrong level of abstraction.

Why can't we have both? Sometimes you *want* to know what's hiding behind that alias, esp. when debugging deeply nested generic code where this is far from obvious. For example, given this C++ code: typedef int* CSPTR; int main() { CSPTR p = "abc"; } g++ 4.6.3 gives this message: /tmp/test.c: In function 'int main()': /tmp/test.c:3:12: error: cannot convert 'const char*' to 'CSPTR {aka int*}' in initialization Both the typedef name and the actual type are specified in the message, which makes it eminently useful in both the case where you're expecting the typedef'd name and the case where you want to know what's behind it. I say dmd should do the same thing. There's no reason to only print one over the other when you can just print both. Full disclosure is the best policy when there's a problem.

Yea, I've got no problem with both (other than sometimes the fully-unaliased one can be really, really long.) But at the very least, the type *as used* needs to be shown. The unaliased form isn't bad to have too, but it's typically of lesser importance.
 T

 -- 
 Democracy: The triumph of popularity over principle. -- C.Bond

Heh, love it :) (Glad it's not the 50's - I'd be accused of being a "dirty commie"!)
Apr 26 2012
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Nick Sabalausky:

 Yea, I've got no problem with both (other than sometimes the 
 fully-unaliased
 one can be really, really long.) But at the very least, the 
 type *as used*
 needs to be shown. The unaliased form isn't bad to have too, 
 but it's
 typically of lesser importance..

See: http://d.puremagic.com/issues/show_bug.cgi?id=5004 Bye, bearophile
Apr 26 2012
prev sibling next sibling parent "Martin Nowak" <dawg dawgfoto.de> writes:
 We can't just use Typedef!(void*) or Typedef!(int) because -=/+= will
 be allowed, which shouldn't be allowed for handles. const(void*) won't
 work either, because you should be allowed to assign one handle to
 another and const forbids that.

struct None; // undefined struct as bottom type alias None* HWND; enum INVALID_HANDLE_VALUE = cast(HWND)-1; static assert(__traits(compiles, {HWND h; h = INVALID_HANDLE_VALUE;})); static assert(!__traits(compiles, {None n;})); static assert(!__traits(compiles, {HWND h; ++h;})); static assert(!__traits(compiles, {HWND h; h + 1;})); HWND foo(HWND h) { return h; } void main() { HWND h; assert(h is null); h = foo(h); assert(h is null); h = foo(INVALID_HANDLE_VALUE); assert(h is INVALID_HANDLE_VALUE); h = foo(null); assert(h is null); }
Apr 26 2012
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Stewart Gordon:

 Windows handles are, AIUI, always of the platform pointer size.
  A zero-size handle type would be useless, as only one distinct 
 handle could exist that way.

struct HWND {} void main() { static assert(HWND().sizeof == 1); } Bye, bearophile
Apr 28 2012
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 4/28/12, Stewart Gordon <smjg_1998 yahoo.com> wrote:
 If it does, it shouldn't, because that struct is of the wrong size.

Yeah sorry, I didn't properly test this but just tried compiling it. It should be the size of the pointer, yup.
Apr 28 2012