string types: const(char)[] and cstring
Walter Bright
newshound1 at digitalmars.com
Sun May 27 12:06:06 PDT 2007
Derek Parnell wrote:
> See, this is what is weird ... I can have an invariant string which can be
> changed, thus making it not really invariant in the English language sense.
> I'm still thinking that "invariant" means "does not change ever".
Where you're going wrong is that there are two parts to a dynamic array
- the contents of the array, and the ptr/length values of the array.
invariant(char)[]
immutalizes (look ma! I coined a new word!) only the contents of the array.
invariant(char[])
immutalizes the contents and the ptr/length values.
> But it seems that I'm wrong ...
>
> invariant char[] x;
> x = "abc".dup; // The string 'x' now contains "abc";
> x = "def".dup; // The string (which is not supposed to change
> // i.e invariant) has been changed to "def".
>
> Now this is counter-intuitive (read: *WEIRD*), no?
The first issue is that you've confused:
invariant char[] x;
with:
invariant(char)[] x;
Remember, there are TWO parts to an array, and the invariantness can be
controlled for either independently, or both. This isn't different from
in C++ there are two parts to a char*, the char part, and the pointer part.
> Okay, I've got that now ... but how to remember that two terms that mean
> the same in English actually mean different things in D <G>
English is imprecise and ambiguous, that's why we have mathematical
languages, and programming languages.
> invariant char[] x; // The data pointed to by 'x' cannot be changed
> // by anything anytime during the execution
> // of the program.
> // (So how do I populate it then? Hmmmm ...)
You can't populate an invariant(char)[] array (which is what you meant,
not invariant char[]). The way to get one is to cast an existing array
to invariant.
> const char[] y; // The data pointed to by 'y' cannot be changed
> // by anything anytime during the execution
> // of the program when using the 'y' variable,
> // however using another variable that also
> // refers to y's data, or some of it, is ok.
Yes, but here again, const(char)[].
> For example ...
>
> void func (const char[] a, char[] b)
> {
> a[0] = 'a'; // fails
> b[0] = 'a'; // succeeds
> }
>
> char[] y = "def".dup;
> func( y, y);
Yup, that's the aliasing issue with const.
> Thanks. So 'final' means that it can be changed (from its initial default
> value) once and only once.
No. 'final' means it is set only at initialization.
> /* --- Scenario #1 --- */
> final int r;
> r = randomer(); // succeeds
Nope, this fails. Try:
final int r = randomer();
> foo(); // fails
>
> int randomer() {
> // Get a random integer between -100 and 100.
> return cast(int)(std.random.rand() % 201) - 100;
> }
> void foo() {
> r = randomer(); // success depends on whether or not 'r'
> // has already been set.
No, this assignment always fails.
> }
>
> Is this a run-time check or a compile time one?
Compile time.
> If run-time, would it be
> possible to somehow 'unfinal' a variable using some implementation
> dependant trickery.
Yes, but the result is undefined behavior. Just like if you went around
the typing system and converted an int into a pointer, and tried to
access data with it. You can do it, but you're on your own with that.
> I have no real knowledge of C++ or its const, and I'm still weirded out by
> it all <G>
I'm beginning to realize that unless one understands how types are
represented at run time, one will never understand const.
More information about the Digitalmars-d-announce
mailing list