View mode: basic / threaded / horizontal-split · Log in · Help
May 16, 2012
Re: arrays: if(null == [ ])
On Wed, 16 May 2012 17:11:58 -0400, deadalnix <deadalnix@gmail.com> wrote:

> Le 16/05/2012 15:12, Steven Schveighoffer a écrit :
>> On Tue, 15 May 2012 04:42:10 -0400, deadalnix <deadalnix@gmail.com>  
>> wrote:
>>
>>> Le 14/05/2012 21:53, Steven Schveighoffer a écrit :
>>>> On Mon, 14 May 2012 15:30:25 -0400, deadalnix <deadalnix@gmail.com>
>>>> wrote:
>>>>
>>>>> Le 14/05/2012 16:37, Steven Schveighoffer a écrit :
>>>>>> Note that [] is a request to the runtime to build an empty array.  
>>>>>> The
>>>>>> runtime detects this, and rather than consuming a heap allocation to
>>>>>> build nothing, it simply returns a null-pointed array. This is 100%
>>>>>> the
>>>>>> right decision, and I don't think anyone would ever convince me (or
>>>>>> Andrei or Walter) otherwise.
>>>>>>
>>>>>
>>>>> Obviously this is the right thing to do !
>>>>>
>>>>> The question is why an array of length 0 isn't nulled ? It lead to
>>>>> confusing semantic here, and can keep alive memory that can't be
>>>>> accessed.
>>>>
>>>> int[] arr;
>>>> arr.reserve(10000);
>>>> assert(arr.length == 0);
>>>>
>>>> -Steve
>>>
>>> The length isn't set to 0 here. You obviously don't want that to be
>>> nulled.
>>
>> The assert disagrees with you :)
>>
>> -Steve
>
> The length IS 0. It IS 0 before the call to reserve. It is never SET to  
> 0.

OK, so it's allowed to be 0 and not-null.  doesn't this lead to the  
confusing semantics you were talking about?

What about this?

int[] arr;
arr.reserve(10000);

int[] arr2 = [1,2,3];
arr2 = arr; // now length has been *set* to 0, should it also be nulled?

But I want arr2 and arr to point at the same thing, maybe I'm not using  
arr anymore.  Maybe I returned it from a function, and I no longer have  
access to arr.

-Steve
May 16, 2012
Re: The more interesting question
On 16-05-2012 23:09, Steven Schveighoffer wrote:
> On Wed, 16 May 2012 17:06:41 -0400, Alex Rønne Petersen <alex@lycus.org>
> wrote:
>
>> On 16-05-2012 22:42, Steven Schveighoffer wrote:
>>> On Wed, 16 May 2012 16:19:36 -0400, Alex Rønne Petersen <alex@lycus.org>
>>> wrote:
>>>
>>>> Theoretically, yes, practically, not really.
>>>>
>>>> void myLog(string msg)
>>>> {
>>>> printf(msg);
>>>> }
>>>
>>> Wait, this should be an error. You need toStringz there.
>>>
>>> -Steve
>>
>> Sorry, I meant:
>>
>> void myLog(string msg)
>> {
>> printf(msg.ptr);
>> }
>>
>> (Which works as expected because string literals are null-terminated.
>> This is also how things work when you pass a string literal to a
>> const(char)* value; it just does "literal".ptr.)
>
> No, it doesn't:
>
> myLog("abc"[0..1]); // prints abc instead of the requested a
>
> string is not necessarily a literal. A literal has a special polysemous
> type, and special properties. An ordinary string does not.
>
> -Steve

I was referring to: myLog("abc");

When you start bringing slicing into the mix, you're bound to make C 
interop harder and more error-prone because of null-termination.

-- 
Alex Rønne Petersen
alex@lycus.org
http://lycus.org
May 16, 2012
Re: The more interesting question
On 05/16/2012 11:08 PM, deadalnix wrote:
> Le 16/05/2012 22:19, Alex Rønne Petersen a écrit :
>>  ...
>> Theoretically, yes, practically, not really.
>>
>> void myLog(string msg)
>> {
>>     printf(msg);
>> }
>>
>
> This is exactly why array shouldn't fallback into pointer silently.
>
> Your code here is flawed and unsafe. You NEED a toStringz here.

It is not unsafe, it is invalid.
May 16, 2012
Re: The more interesting question
On Wed, May 16, 2012 at 11:22:48PM +0200, Alex Rønne Petersen wrote:
> On 16-05-2012 23:09, Steven Schveighoffer wrote:
> >On Wed, 16 May 2012 17:06:41 -0400, Alex Rønne Petersen <alex@lycus.org>
> >wrote:
[...]
> >>void myLog(string msg)
> >>{
> >>printf(msg.ptr);
> >>}
> >>
> >>(Which works as expected because string literals are null-terminated.
> >>This is also how things work when you pass a string literal to a
> >>const(char)* value; it just does "literal".ptr.)
> >
> >No, it doesn't:
> >
> >myLog("abc"[0..1]); // prints abc instead of the requested a
> >
> >string is not necessarily a literal. A literal has a special polysemous
> >type, and special properties. An ordinary string does not.
> >
> >-Steve
> 
> I was referring to: myLog("abc");
> 
> When you start bringing slicing into the mix, you're bound to make C
> interop harder and more error-prone because of null-termination.
[...]

I think his point is that myLog is poorly written because it declares
itself to have a string parameter, yet does not function properly when
called with a string that isn't NULL-terminated (e.g. a string slice).


T

-- 
Let's not fight disease by killing the patient. -- Sean 'Shaleh' Perry
May 16, 2012
Re: The more interesting question
On Wednesday, May 16, 2012 19:52:07 Alex Rønne Petersen wrote:
> I guess we can conclude that one should not use 'null' or 'is' for
> arrays unless absolutely necessary. '[]' and '==' should probably do for
> the majority of code.

The only reason to use is is if you're checking for identity rather than 
equality. == checks for equality. It should be clear when you need one or the 
other.

null and [] are essentially equivalent, so it doesn't really matter which you 
use.

However, I'd argue that using == with null or [] is a bad move, because it 
tends to show a lack of understanding, simply because it's so natural for 
people to try and check whether something is null by comparing against ==, and 
that _doesn't work_. So, if you want to check whether an array is empty, use 
empty or length == 0, whereas if you want to check whether an array is null, 
then use is null.

But aside from the issues of clarity surrounding checking whether an array is 
empty by using == null or == [], I think that it's quite clear when == or is 
should be used. If it's not, it's because you don't understand the differences 
between the two.

- Jonathan M Davis
May 16, 2012
Re: arrays: if(null == [ ])
On Wednesday, May 16, 2012 09:18:38 Steven Schveighoffer wrote:
> but I still think we should discourage using null as a
> sentinel, it leads to confusing code.

If null were actually properly differentiated from empty, then this wouldn't be 
a problem, but it's not. It _should_ be possible to treat null as a sentinel. 
The fact that it causes issues is a major flaw in the language IMHO. But given 
that flaw, it does very quickly become error-prone to use null as a sentinel. 
In general, I'd say that the only reasonable place to do so is when returning 
an array (and especially a string) from a function. The return value can then 
be immeditely checked with is null before it has the chance to have something 
happen to it which could cause it to be empty but non-null.

- Jonathan M Davis
May 17, 2012
Re: The more interesting question
On 16-05-2012 00:20, deadalnix wrote:
> Le 15/05/2012 21:57, Andrew Wiley a écrit :
>> On Tue, May 15, 2012 at 11:46 AM, deadalnix <deadalnix@gmail.com
>> <mailto:deadalnix@gmail.com>> wrote:
>>
>> Le 15/05/2012 18:19, Gor Gyolchanyan a écrit :
>>
>>
>>
>> On Tue, May 15, 2012 at 7:51 PM, Christophe
>> <travert@phare.normalesup.org
>> <mailto:travert@phare.normalesup.org>
>> <mailto:travert@phare.__normalesup.org
>> <mailto:travert@phare.normalesup.org>>> wrote:
>>
>> using printf will lead to a bug each time the programmer
>> forget the
>> trailing
>> \0.
>>
>>
>> First of all, printf shouldn't be used! There's writef and it's
>> superior
>> to printf in any way!
>> Second of all, if the zero-termination of literals are to be
>> removed,
>> the literals will no longer be accepted as a pointer to a character.
>> The appropriate type mismatch error will force the user to use
>> toUTF8z
>> to get ht e zero-terminated utf-8 version of the original string.
>> In case it's a literal, one could use the compile-time version of
>> toUTF8z to avoid run-time overhead.
>> This all doesn't sound like a bad idea to me. I don't see any
>> security
>> or performance flaws in this scheme.
>> --
>> Bye,
>> Gor Gyolchanyan.
>>
>>
>> May god ear you !
>>
>>
>> Unfortunately, using writef/writefln would make DRuntime depend on
>> Phobos, which is unacceptable.
>>
>
> druntime isn't supposed to printf stuff.

It's called debugging. ;)

-- 
Alex Rønne Petersen
alex@lycus.org
http://lycus.org
May 17, 2012
Re: arrays: if(null == [ ])
Le 16/05/2012 23:15, Steven Schveighoffer a écrit :
> On Wed, 16 May 2012 17:11:58 -0400, deadalnix <deadalnix@gmail.com> wrote:
>
>> Le 16/05/2012 15:12, Steven Schveighoffer a écrit :
>>> On Tue, 15 May 2012 04:42:10 -0400, deadalnix <deadalnix@gmail.com>
>>> wrote:
>>>
>>>> Le 14/05/2012 21:53, Steven Schveighoffer a écrit :
>>>>> On Mon, 14 May 2012 15:30:25 -0400, deadalnix <deadalnix@gmail.com>
>>>>> wrote:
>>>>>
>>>>>> Le 14/05/2012 16:37, Steven Schveighoffer a écrit :
>>>>>>> Note that [] is a request to the runtime to build an empty array.
>>>>>>> The
>>>>>>> runtime detects this, and rather than consuming a heap allocation to
>>>>>>> build nothing, it simply returns a null-pointed array. This is 100%
>>>>>>> the
>>>>>>> right decision, and I don't think anyone would ever convince me (or
>>>>>>> Andrei or Walter) otherwise.
>>>>>>>
>>>>>>
>>>>>> Obviously this is the right thing to do !
>>>>>>
>>>>>> The question is why an array of length 0 isn't nulled ? It lead to
>>>>>> confusing semantic here, and can keep alive memory that can't be
>>>>>> accessed.
>>>>>
>>>>> int[] arr;
>>>>> arr.reserve(10000);
>>>>> assert(arr.length == 0);
>>>>>
>>>>> -Steve
>>>>
>>>> The length isn't set to 0 here. You obviously don't want that to be
>>>> nulled.
>>>
>>> The assert disagrees with you :)
>>>
>>> -Steve
>>
>> The length IS 0. It IS 0 before the call to reserve. It is never SET
>> to 0.
>
> OK, so it's allowed to be 0 and not-null. doesn't this lead to the
> confusing semantics you were talking about?
>
> What about this?
>
> int[] arr;
> arr.reserve(10000);
>
> int[] arr2 = [1,2,3];
> arr2 = arr; // now length has been *set* to 0, should it also be nulled?
>
> But I want arr2 and arr to point at the same thing, maybe I'm not using
> arr anymore. Maybe I returned it from a function, and I no longer have
> access to arr.
>
> -Steve

That make sense :D
May 17, 2012
Re: arrays: if(null == [ ])
On Thu, 17 May 2012 00:08:49 +0100, Jonathan M Davis <jmdavisProg@gmx.com>  
wrote:

> On Wednesday, May 16, 2012 09:18:38 Steven Schveighoffer wrote:
>> but I still think we should discourage using null as a
>> sentinel, it leads to confusing code.
>
> If null were actually properly differentiated from empty, then this  
> wouldn't be
> a problem, but it's not. It _should_ be possible to treat null as a  
> sentinel.
> The fact that it causes issues is a major flaw in the language IMHO. But  
> given
> that flaw, it does very quickly become error-prone to use null as a  
> sentinel.
> In general, I'd say that the only reasonable place to do so is when  
> returning
> an array (and especially a string) from a function. The return value can  
> then
> be immeditely checked with is null before it has the chance to have  
> something
> happen to it which could cause it to be empty but non-null.

I want to re-re-re-register my dismay in the situation also.  For me it  
always comes back to.. I can do it with a pointer.. a pointer!  Why not an  
array?!?

R

-- 
Using Opera's revolutionary email client: http://www.opera.com/mail/
May 18, 2012
Re: The more interesting question
"Steven Schveighoffer" , dans le message (digitalmars.D:167556), a
> toStringz can allocate a new block in order to ensure 0 gets added.  This  
> is ludicrous!
> 
> You are trying to tell me that any time I want to call a C function with a  
> string literal, I have to first heap-allocate it, even though I *know*  
> it's safe.

How about "mystring\0".ptr ?
4 5 6 7 8 9
Top | Discussion index | About this forum | D home