Jump to page: 1 2
Thread overview
.init property for char[] type
Sep 22, 2009
Justin Johansson
Sep 22, 2009
Jeremie Pelletier
Sep 22, 2009
Justin Johansson
Sep 22, 2009
Justin Johansson
Sep 22, 2009
Daniel Keep
Sep 22, 2009
Justin Johansson
Sep 22, 2009
Jeremie Pelletier
Sep 22, 2009
Justin Johansson
Sep 22, 2009
Jeremie Pelletier
Sep 22, 2009
Jeremie Pelletier
Sep 22, 2009
Justin Johansson
Sep 23, 2009
Michel Fortin
Sep 23, 2009
Jeremie Pelletier
Sep 24, 2009
Walter Bright
Sep 22, 2009
Justin Johansson
September 22, 2009
In a templated class (D1.0) along lines ...

class Foo(T) {
//..
  static T bar() { return T.init; }
//..
}

Foo!(int).bar() returns 0 and Foo!(char[]).bar() returns nil.

I'd much prefer (at least for my purposes) that (char[]).init returned an empty string rather than effectively a null pointer.  Is there a convenient solution for this, e.g. by specializing just the bar method of class Foo when T is char[], or by some other means?

Maybe this type of question best be asked on D.learn, but I do wonder if an empty string is a more reasonable initializer for char[] .. well maybe not .. I don't know .. I yield to your sensibilities.

Thanks to all.

September 22, 2009
Justin Johansson wrote:
> In a templated class (D1.0) along lines ...
> 
> class Foo(T) {
> //..
>   static T bar() { return T.init; }
> //..
> }
> 
> Foo!(int).bar() returns 0 and Foo!(char[]).bar() returns nil.
> 
> I'd much prefer (at least for my purposes) that (char[]).init returned an empty string rather than effectively a null pointer.  Is there a convenient solution for this, e.g. by specializing just the bar method of class Foo when T is char[], or by some other means?
> 
> Maybe this type of question best be asked on D.learn, but I do wonder if an empty string is a more reasonable initializer for char[] .. well maybe not .. I don't know .. I yield to your sensibilities.
> 
> Thanks to all.
> 

You could use a custom type, which would solve your .init problem:
typedef string myString = "";

Or you could specialize your bar():

static T bar() {
    static if(isSomeString!T)
        return "";
    else
        return T.init;
}

I myself favor a null initializer, since char[] is a reference type, not a value type, it only makes sense to initialize it to a null reference.
September 22, 2009
On Tue, Sep 22, 2009 at 8:07 AM, Justin Johansson <procode@adam-dott-com.au> wrote:
> In a templated class (D1.0) along lines ...
>
> class Foo(T) {
> //..
>  static T bar() { return T.init; }
> //..
> }
>
> Foo!(int).bar() returns 0 and Foo!(char[]).bar() returns nil.
>
> I'd much prefer (at least for my purposes) that (char[]).init returned an empty string rather than effectively a null pointer.  Is there a convenient solution for this, e.g. by specializing just the bar method of class Foo when T is char[], or by some other means?
>
> Maybe this type of question best be asked on D.learn, but I do wonder if an empty string is a more reasonable initializer for char[] .. well maybe not .. I don't know .. I yield to your sensibilities.
>
> Thanks to all.

There's no real difference between an empty string and a null reference. Both have 0 length.
September 22, 2009
Jarrett Billingsley Wrote:

> On Tue, Sep 22, 2009 at 8:07 AM, Justin Johansson
> >
> > Maybe this type of question best be asked on D.learn, but I do wonder if an empty string is a more reasonable initializer for char[] .. well maybe not .. I don't know .. I yield to your sensibilities.
> >
> There's no real difference between an empty string and a null reference. Both have 0 length.

Big difference if you pass char[] variable .ptr to a C function.


static if ( typeid(T) is typeid(char[])) {

		}

		else {
			init_sequence = new ExactlyOne!(T)( T.init);
		}

Tks Jeremie got specialized method working with
September 22, 2009
Justin Johansson Wrote:

Scratch that last garbled reply .. finger trouble.

Was going to say that ...


> > There's no real difference between an empty string and a null reference. Both have 0 length.

Big difference if you pass char[] variable .ptr to a C function.


And thanks Jeremie, got specialized method working with
static if ( typeid(T) is typeid(char[])) {
  // ..
}

else {
  // ..
}

Cheers
Justin Johansson

September 22, 2009
In general, if you pass a string to a C function you should send it through toStringz first.  If you don't, you're just begging for segfaults.

Justin Johansson wrote:
>>> There's no real difference between an empty string and a null reference. Both have 0 length.
> 
> Big difference if you pass char[] variable .ptr to a C function.
September 22, 2009
Daniel Keep Wrote:

> > Big difference if you pass char[] variable .ptr to a C function.

> In general, if you pass a string to a C function you should send it through toStringz first.  If you don't, you're just begging for segfaults.

Agreed .. fair enough.

Actually I'm more interested in the semantics for default initialized char[].
Does it have exactly the same semantics as an empty string (in general D or runtime library, Phobos et. al. context)?


September 22, 2009
Justin Johansson wrote:
> Daniel Keep Wrote:
> 
>>> Big difference if you pass char[] variable .ptr to a C function.
> 
>> In general, if you pass a string to a C function you should send it
>> through toStringz first.  If you don't, you're just begging for segfaults.
> 
> Agreed .. fair enough.
> 
> Actually I'm more interested in the semantics for default initialized char[].
> Does it have exactly the same semantics as an empty string (in general D or runtime library, Phobos et. al. context)?

It isn't the same semantics:
a null array is {0, null}, while an empty array is {0, &zero} where zero is of type 'char zero = 0;' since string literals are zero terminated.

Their usage is mostly the same, you can concatenate both of them, append  to both of them, and etc, all giving the same results. Where it makes a difference is when you need to enforce an invariant that .ptr is not null. Calling toStringz on either will give the same C string: a pointer to a zero value.

You have to remember that arrays are reference types; they are perfectly valid without referenced data. Think of pointers or objects for example, which are also reference types. Besides, if you initialize character arrays to "", what do you initialize other arrays to, and other reference types to? It just wouldn't be consistent.
September 22, 2009
On Tue, 22 Sep 2009 09:53:52 -0400, Justin Johansson <procode@adam-dott-com.au> wrote:

> Daniel Keep Wrote:
>
>> > Big difference if you pass char[] variable .ptr to a C function.
>
>> In general, if you pass a string to a C function you should send it
>> through toStringz first.  If you don't, you're just begging for segfaults.
>
> Agreed .. fair enough.
>
> Actually I'm more interested in the semantics for default initialized char[].
> Does it have exactly the same semantics as an empty string (in general D or runtime library, Phobos et. al. context)?

A null string *is* an empty string, but an empty string may not be a null string.

The subtle difference is that the pointer points to null versus some data.

A non-null empty string:

 - May be pointing to heap data, therefore keeping the data from being collected.
 - May reallocate in place on appending (a null string always must allocate new data on append).

It's a difficult concept to get, but an array is really a hybrid type between a reference and a value type.  The array is actually a value type struct with a pointer reference and a length value.  If the length is zero, then the pointer value technically isn't needed, but in subtle cases, it makes a difference.  When you copy the array, the length behaves like a value type (changing the length of one array doesn't affect the other), but the array data is referenced (changing an element of the array *does* affect the other).

I think plans are to make the array a full reference type, and leave slices as these structs (in D2).  This probably will clear up a lot of confusion people have.

I hope this helps...

Oh, and BTW, you can pass string literals to C functions, but *not* char[] variables.  Always pass them through toStringz.  It generally does not take much time/resources to add the zero.

-Steve
September 22, 2009
Jeremie Pelletier Wrote:
> Besides, if you initialize character arrays to "", what do you initialize other arrays to, and other reference types to? It just wouldn't be consistent.

Consistency.  Since when is that an argument?

Just to be a PITA, pick the inconsistent row in the table below (from spec_D1.00.pdf).
The row ordering of the the table has been shuffled just to make it a bit more difficult to spot :-)

short.init    0
int.init        0
bool.init     false
byte.init     0
double.init  double.nan
long.init     0L

« First   ‹ Prev
1 2