www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Finding out about D - 101

reply Steve Teale <steve.teale britseyeview.com> writes:
OK, so let's find out about strings. D does not have 'string' as a built in
type. It is just an alias for invariant(char[]). So what is it?

Well, you can find out quite a bit by compiling and running:

import std.stdio;

struct S
{
   size_t len;
   void* p;
   int xtra;
}

void main()
{
   string a;
   string b = "";
   char[] ca = ['a','b','c','d'];
   string c = "abcd";

   writefln("(a == b) %s", (a == b));

   S* s = cast(S*) &b;

   writefln("a: [%s] %s %08x, %d", a, (a is null), a.ptr, a.length);
   writefln("b: [%s] %s %08x, %d", b, (b is null), b.ptr, b.length);

   writefln("b as S: [%08x] %d [%08x]", s.p, s.len, s.xtra);
   writefln("char at *b.ptr = [%s] (%d)", *b.ptr, cast(ubyte) *b.ptr);
   s = cast(S*) &ca;
   writefln("ca as S: [%08x] %d [%08x]", s.p, s.len, s.xtra);
   s = cast(S*) &c;
   writefln("c as S: [%08x] %d [%08x]", s.p, s.len, s.xtra);
}

This tells me that a string in D is a sequence of characters (whatever that
might mean) in memory, prefixed by a size_t length. Of  course, that's not to
say there is no more to it, but the values for 'xtra' don't give us much clue.
If there was some other member of struct S, I'd kind of expect to see bit flags
there indicating whether the array of char was invariant, const, or fair game.

So I'm left with the question as to how does 'invariant' have teeth?
May 11 2009
next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Mon, 11 May 2009 12:42:17 -0400, Steve Teale  
<steve.teale britseyeview.com> wrote:

 OK, so let's find out about strings. D does not have 'string' as a built  
 in type. It is just an alias for invariant(char[]). So what is it?

 Well, you can find out quite a bit by compiling and running:

 import std.stdio;

 struct S
 {
    size_t len;
    void* p;
    int xtra;
 }

 void main()
 {
    string a;
    string b = "";
    char[] ca = ['a','b','c','d'];
    string c = "abcd";

    writefln("(a == b) %s", (a == b));

    S* s = cast(S*) &b;

    writefln("a: [%s] %s %08x, %d", a, (a is null), a.ptr, a.length);
    writefln("b: [%s] %s %08x, %d", b, (b is null), b.ptr, b.length);

    writefln("b as S: [%08x] %d [%08x]", s.p, s.len, s.xtra);
    writefln("char at *b.ptr = [%s] (%d)", *b.ptr, cast(ubyte) *b.ptr);
    s = cast(S*) &ca;
    writefln("ca as S: [%08x] %d [%08x]", s.p, s.len, s.xtra);
    s = cast(S*) &c;
    writefln("c as S: [%08x] %d [%08x]", s.p, s.len, s.xtra);
 }

 This tells me that a string in D is a sequence of characters (whatever  
 that might mean) in memory, prefixed by a size_t length. Of  course,  
 that's not to say there is no more to it, but the values for 'xtra'  
 don't give us much clue. If there was some other member of struct S, I'd  
 kind of expect to see bit flags there indicating whether the array of  
 char was invariant, const, or fair game.

 So I'm left with the question as to how does 'invariant' have teeth?
invariant is not a runtime flag, but rather a type modifier. The teeth of invariance only exist during compilation, once you're in runtime, the expectation is that the compiler will have weeded out all your attempts to change the invariant data, so no need to keep track of its invariance. It is not immune to casting. And BTW, string is invariant(char)[], not invariant(char[]), which is a distinct difference. The former is a mutable array of invariant characters, the latter is an invariant array of invariant characters. You can't change the length or reassign an invariant(char[]), but you can reassign/append to an invariant(char)[]. The xtra flags do not exist. You are printing out garbage data on the stack (most likely the pointer field of ca). -Steve
May 11 2009
parent Steve Teale <steve.teale britseyeview.com> writes:
Steven Schveighoffer Wrote:

 This tells me that a string in D is a sequence of characters (whatever  
 that might mean) in memory, prefixed by a size_t length. Of  course,  
 that's not to say there is no more to it, but the values for 'xtra'  
 don't give us much clue. If there was some other member of struct S, I'd  
 kind of expect to see bit flags there indicating whether the array of  
 char was invariant, const, or fair game.

 So I'm left with the question as to how does 'invariant' have teeth?
invariant is not a runtime flag, but rather a type modifier. The teeth of invariance only exist during compilation, once you're in runtime, the expectation is that the compiler will have weeded out all your attempts to change the invariant data, so no need to keep track of its invariance. It is not immune to casting. And BTW, string is invariant(char)[], not invariant(char[]), which is a distinct difference. The former is a mutable array of invariant characters, the latter is an invariant array of invariant characters. You can't change the length or reassign an invariant(char[]), but you can reassign/append to an invariant(char)[]. The xtra flags do not exist. You are printing out garbage data on the stack (most likely the pointer field of ca). -Steve
Great, so there are experienced D programmers checking on this newsgroup! I'd kind of figured out from the test program that the invariant thing was just compile time, but thanks for pointing out my misconception about the string alias. I should read things more carefully. - Also Steve
May 11 2009
prev sibling parent BCS <none anon.com> writes:
Hello Steve,

 This tells me that a string in D is a sequence of characters (whatever
 that might mean) in memory, prefixed by a size_t length. Of  course,
 that's not to say there is no more to it, but the values for 'xtra'
 don't give us much clue. If there was some other member of struct S,
 I'd kind of expect to see bit flags there indicating whether the array
 of char was invariant, const, or fair game.
T[] is a length/pointer pair. If the data ends up being right after that bit, then it's just a coincidence.
 
 So I'm left with the question as to how does 'invariant' have teeth?
 
const and invariant are both implemented completely at compile time so they don't show up the final code at all.
May 11 2009