One more shot at this const thing.
Dave
Dave_member at pathlink.com
Thu Jul 27 09:09:09 PDT 2006
I can still hear the horse whinnying, so I thought I'd beat it with a
slightly different club <g> And that would be taking the best of C++
const modified to be more in line with D goals. I don't think the exact
same has been outlined before, so if it has I apologize.
IIRC Walter's primary (and valid IMO) arguments against C++ const are:
1) it does not guarantee anything to a code maintainer
2) it does not guarantee anything to the compiler
3) it's ugly (const sprinkled everywhere).
But, I'm beginning to think that maybe C++'s const [with roughly the
same compiler enforcement rules but slightly different semantics and
syntax more applicable to D] would work Ok.
Also maybe const would apply only to built-in reference types (including
class objects) and not pointers, justifiable because D has these
built-in whereas C++ doesn't. The same 'const' would not apply to value
types either, for simplicity.
Consider the following C++ code:
class C
{
public:
const char *str;
C(const char *val): str(val)
{
}
char
const * // const reference data return value
foo(char // const reference data
const * // const reference data
const val // const reference
) const // const object
{
val = new char[100]; // error: assignment of read-only parameter
val[0] = 'a'; // error: assignment of read-only location
str = new char[100]; // error: assign to member of const object
str[0] = 'a'; // error: assignment of read-only location
return str;
}
int i;
void bar(int val) { i = val; }
int baz() const
{
return i;
}
};
int main()
{
C c("test string");
char* str, *st2;
st2 = c.foo(str); // error: invalid conversion const char* to char*
const char* st3 = c.foo(str); // Ok
return 0;
}
int bar(const C &c)
{
c.i = 10; // error: assignment of data-member in read-only structure
c.foo("test");
c.bar(10); // error: discards qualifiers
return c.baz() * 10;
}
So in D this would be:
class C
{
const char[] str;
this(char[] val)
{
str = val;
}
// const reference & data for return value, argument and object
// ugly, but necessary and not nearly as ugly as C++
const char[] foo(const char[] val) const
{
val = new char[100]; // error: assignment of read-only parameter
val[0] = 'a'; // error: assignment of read-only location
str = new char[100]; // error: assign to member of const object
str[0] = 'a'; // error: assignment of read-only location
return str;
}
int i;
void bar(int val) { i = val; }
int baz() const
{
return i;
}
}
void main()
{
C c = new C("test string");
char[] str, st2;
st2 = c.foo(str); // error: conversion from const char[] to char[]
const char[] st3 = c.foo(str); // Ok
// The C++ rules plus all this looks readily enforceable by the
// compiler to me.
st2 = cast(char[])c.foo(str); // error: invalid cast
st2 = st3; // error
str[0] = st3[0]; // Ok
st3 = st2; // error
st3 = cast(const char[]) st2; // error: invalid cast
st3[0] = st2[0]; // error
const char* ptr; // error, invalid type (how much broken code?)
}
int bar(const C c)
{
c.i = 10; // error
c.foo("test"); // Ok
c.bar(10); // error
return c.baz * 10; // Ok
}
The compiler can't enforce everything you can do to a const in D. To
make it so that const can actually be meaningful, additional language
could be added to the spec. That language could be as simple as
something like: "subverting const can result in undefined behavior".
This spec. language is justifiable (again) because D has built-in
reference types that C++ doesn't, and it's done like that for numerous
other things in D (e.g.: missing return statements and order of
evaluation) so it's not inconsistent.
I think all of the above is enforceable for a compiler (so it's
meaningful in the general case) and also is not as ugly or convoluted as
C++ syntax. I believe it takes care of the issues of a) not having any
help by the compiler on enforcing COW and b) being able to pass class
and other reference objects into a function and 'guarantee' that the
object not be modified inside the function.
The actual keyword used is not important.
One of the major reasons Java is slow is because of all the data
duplication that needs to go on. D needs to avoid this... Billions of $
and years of research into Java GC and runtime optimizers has not solved
the problem, leading me to believe it never will. If D gets the same rap
as Java on the perf. issues, game over. Likewise if programmer-only
enforced COW turns out to be a bug-ridden maintenance nightmare for
corporate programmers out there.
Thoughts on this method of 'const' for D?
Thanks,
- Dave
More information about the Digitalmars-d
mailing list