Thread overview
DMD 0.123: Comparison of void[] causes Win32 Exception
May 15, 2005
Burton Radons
May 15, 2005
xs0
May 15, 2005
Burton Radons
May 16, 2005
Stewart Gordon
May 15, 2005
Ben Hinkle
May 15, 2005
Burton Radons
May 15, 2005
Burton Radons
May 18, 2005
Walter
May 15, 2005
This code causes a Win32 Exception on DMD 0.123 when executed:

   void main()
   {
       new void[40] == new void[40];
   }

This will happen when comparing any non-empty void array.  It should work properly.  Casting to byte[] first makes it work.
May 15, 2005
Burton Radons wrote:
> This code causes a Win32 Exception on DMD 0.123 when executed:
> 
>    void main()
>    {
>        new void[40] == new void[40];
>    }
> 
> This will happen when comparing any non-empty void array.  It should work properly.  Casting to byte[] first makes it work.

how would you compare an any-type with an any-type (which I believe is the meaning of void pointers/arrays)? what it should be, though, is a compile time error..


xs0
May 15, 2005
xs0 wrote:

> Burton Radons wrote:
> 
>> This code causes a Win32 Exception on DMD 0.123 when executed:
>>
>>    void main()
>>    {
>>        new void[40] == new void[40];
>>    }
>>
>> This will happen when comparing any non-empty void array.  It should work properly.  Casting to byte[] first makes it work.
> 
> 
> how would you compare an any-type with an any-type (which I believe is the meaning of void pointers/arrays)? what it should be, though, is a compile time error..

Void arrays are not consistent with the rest of the void implementation - they're specially defined as an array of memory, so they have identity and equality but not order.  If they were consistent they wouldn't contain any data.

Failing the code is unacceptable, that would wreak havoc with templating.  D's void support is still bad - we need void arguments and void variables.  It's a regular value type, there just aren't any values for it.
May 15, 2005
"Burton Radons" <burton-radons@smocky.com> wrote in message news:d66l3j$2bmc$1@digitaldaemon.com...
> This code causes a Win32 Exception on DMD 0.123 when executed:
>
>    void main()
>    {
>        new void[40] == new void[40];
>    }
>
> This will happen when comparing any non-empty void array.  It should work properly.  Casting to byte[] first makes it work.

I don't think that's a bug. Array comparison works element-wise. "void[]" explicitly means the elements are inaccessible. Implicitly casting to byte[] wouldn't be obeying the meaning of void[].


May 15, 2005
Ben Hinkle wrote:

> "Burton Radons" <burton-radons@smocky.com> wrote in message news:d66l3j$2bmc$1@digitaldaemon.com...
> 
>>This code causes a Win32 Exception on DMD 0.123 when executed:
>>
>>   void main()
>>   {
>>       new void[40] == new void[40];
>>   }
>>
>>This will happen when comparing any non-empty void array.  It should work properly.  Casting to byte[] first makes it work.
> 
> 
> I don't think that's a bug. Array comparison works element-wise. "void[]" explicitly means the elements are inaccessible. Implicitly casting to byte[] wouldn't be obeying the meaning of void[]. 

You don't think it's a bug when the runtime crashes?  ;)

D void is not ANSI C void.  D void is a unit of memory (its size is 1, amongst other qualities).  Memory has the properties of identity and equality.

I'd rather there be an octet type myself, that can't be implicitly casted to/from any integer types.  That way void[] could really be an array of C void and templating would work uniformly.  But it's not, D void already is an octet, and in any case templating MUST work uniformly so it requires the comparison.

I should also emphasize that I can't cast it to a byte array because it's not a byte array.  Void's special quality is that it has no type, so it can be garbage-collected properly; an array of memory can contain all types.  Once I turn that into a byte array (and don't tell me to retain a reference to the void array - an optimising compiler could take it out from under your feet in many circumstances) the GC could free an object referenced within it.  The only way to defeat that, proof all the way to the end of infinity regardless of any advances in compiler optimisation technology, is to only cast out the void[] into its true underlying type(s).

Casting is a hideously dangerous operation when applied to pointers that's only valid when used with union and void.  Anywhere else is undefined.  Off-topic, but one benefit of the standard boxer is that it hides in a proper, secure implementation most situations where you'd need (as opposed to want) to cast pointers.
May 15, 2005
Wow, late, I made some confusing statements here.  I'll try this again when I've slept some, and give some examples of what optimising compilers are free to do with code.
May 16, 2005
Burton Radons wrote:
> xs0 wrote:
> 
>> Burton Radons wrote:
>>
>>> This code causes a Win32 Exception on DMD 0.123 when executed:
>>>
>>>    void main()
>>>    {
>>>        new void[40] == new void[40];
>>>    }
>>>
>>> This will happen when comparing any non-empty void array.  It should work properly.  Casting to byte[] first makes it work.
>>
>> how would you compare an any-type with an any-type (which I believe is the meaning of void pointers/arrays)? what it should be, though, is a compile time error..

If this is to be legal, it should be a bit compare.  This could indeed be useful if you're writing a file compare utility.

> Void arrays are not consistent with the rest of the void implementation - they're specially defined as an array of memory, so they have identity and equality but not order.  If they were consistent they wouldn't contain any data.

The use of void with two distinct purposes seems to be a carry-over from C, where a void pointer simply represents an address in memory without regard to what is in it.  Similarly, a D void[] is a block of memory without regard to what is in it.  OK, so logically void[] ought to mean an array of nothings.

Can you think of a better name for a block of memory of unspecified data type?  I guess that byte[] (which it resembles in behaviour) could be used, but if byte[] replaced void[] then every array type would need to be implicitly convertible to a byte[].  (Indeed, should we pick byte[] or ubyte[] as the standard?)

> Failing the code is unacceptable, that would wreak havoc with templating.  D's void support is still bad - we need void arguments and void variables.  It's a regular value type, there just aren't any values for it.

What would a void argument/variable be?  Simply the ability to do something like

    void qwert() { ... }
    void yuiop(void asdfg) { ... }

    void main() {
        void hjkl = qwert();
        yuiop(hjkl);
    }

Not sure what the point of this would be....

Speaking of which, what should void.sizeof return?  As a return type, it's effectively zero.  I always thought that in C sizeof(void) ought to equal 0.  (According to gcc, it's 1 in C and be an illegal expression in C++.)  In void* arithmetic and void[] slicing, it's effectively 1.  And in gdc 0.11, I get void.sizeof == 1.

Stewart.

-- 
My e-mail is valid but not my primary mailbox.  Please keep replies on the 'group where everyone may benefit.
May 18, 2005
Fixed for next update.