| Thread overview | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
September 22, 2009 .init property for char[] type | ||||
|---|---|---|---|---|
| ||||
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 Re: .init property for char[] type | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Justin Johansson | 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 Re: .init property for char[] type | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Justin Johansson | 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 Re: .init property for char[] type | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jarrett Billingsley | 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 Re: .init property for char[] type | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Justin Johansson | 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 Re: .init property for char[] type | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Justin Johansson |
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 Re: .init property for char[] type | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Daniel Keep | 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 Re: .init property for char[] type | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Justin Johansson | 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 Re: .init property for char[] type | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Justin Johansson | 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 Re: .init property for char[] type | ||||
|---|---|---|---|---|
| ||||
Posted in reply to Jeremie Pelletier | 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
| |||
Copyright © 1999-2021 by the D Language Foundation
Permalink
Reply