digitalmars.D - struct vs. class, int vs. char.
- MLT (38/38) Apr 28 2009 D is really an amazing language! It really is everything that C++ did no...
- bearophile (18/37) Apr 28 2009 Yep.
- Steven Schveighoffer (12/25) Apr 28 2009 This has been discussed. Most people agree that the behavior should be ...
- MLT (6/14) Apr 28 2009 Pretty nice. It would be even nicer if you had the following:
- Andrei Alexandrescu (43/45) Apr 28 2009 Could you please give a little more detail?
- bearophile (20/25) Apr 28 2009 My experience with Scala is near zero, I have written and compiled only ...
- Jarrett Billingsley (27/51) Apr 28 2009 be interchangeable - one might implement something as a class and later...
- grauzone (14/23) Apr 28 2009 Often I'd wish to statically allocate an object in the current context,
- Denis Koroskin (7/33) Apr 28 2009 I belive it could be implemented as a library type, using Scope(T) templ...
- grauzone (11/17) Apr 28 2009 I don't like that approach to replace random language features by
- Denis Koroskin (14/31) Apr 28 2009 No way! But Scope!(Bar) would be implicitly castable to Bar (just not vi...
- Daniel Keep (13/14) Apr 28 2009 Scope stack-allocating is an optimisation. It doesn't guarantee it
- Denis Koroskin (42/56) Apr 29 2009 Is that a challenge?
- Denis Koroskin (55/55) Apr 29 2009 Here is another example:
- Denis Koroskin (5/7) Apr 29 2009 This could be temporarily worked around by little template magic:
- Tomas Lindquist Olsen (8/16) Apr 28 2009 It pretty much boils down to this (mostly said in other replies)
- Denis Koroskin (8/29) Apr 28 2009 Someone ought to post a feature request to make arrayliterals immutable ...
- grauzone (3/40) Apr 28 2009 Why not auto-allocate? Writing that .dup all the time is going to be
- Don (8/53) Apr 29 2009 I think it's pretty unlikely that you'd want to do that. It's far more
- Georg Wrede (6/9) Apr 29 2009 There was a huge discussion about null strings a few years ago.
- Steven Schveighoffer (6/10) Apr 29 2009 Why is this more desirable than just:
D is really an amazing language! It really is everything that C++ did not manage to be, at least as far as my limited experience with it shows. I noticed a couple of "problems" with it, and wanted to comment on them. It could easily be that these comments just stem from my ignorance. 1. struct vs. class As far as I understand, these two reserved words, that in C++ mean very similar things, in D are very different. A class variable is "really" a pointer, whereas a struct is directly allocated memory. What I don't like is that it seems that structs and classes should almost be interchangeable - one might implement something as a class and later want it to be a struct, or vice versa. It almost is actually a local decision. I might want something to be a class in one place, and a struct in another. And, it seems that struct and class refer to several different things: (1) struct and class are allocated in different places, (2) struct is supposed to ensure its structure, and (3) struct is copied by value, whereas class by reference. It seems to me that these are 3 different issues, and one should have control over them separately. I find this example a bit strange: struct S { int x;} class C {int x;} void main() { { S x ; x.x = 1 ; S y = x ; y.x =2 ; writefln(x.x) ; // x.x is 1 } { C x = new C ; x.x = 1; C y = x ; y.x = 2 ; writefln(x.x) ; // x.x is 2 } } I would have preferred to declare directly that the variable y takes or doesn't take a reference when assigned. Otherwise, it seems to me that a program that uses both (struct and class) can get mightily confusing. Maybe the solution is to not use struct (which is I guess what is recommended unless you really need it.) 2. char[] vs. int[] I think it is strange that char[] x = "1234" ; x[0] = '4' ; Produces a run time error, but int[] x = [1,2,3,4] ; x[0] = 4 ; Doesn't. I think that they both should, or both shouldn't - to be consistent (and it would be better if they both didn't). Best would be again, to allow the programmer to specify where the array (or other stuff) should be stored. 3. Builtin types vs. classes (Here I probably am just missing the right phobos reference). D's builtin structures are very rich. Associative arrays with arbitrary keys! Given that, it is even sadder than it is in C++, that one can not inherit from the basic types. I want to implement something that is basically an associative array of one of my classes, with additional features. To do that, I will probably have to put the associative array as a component, and redefine all components/operations, or inherit from an associative array in a library...
Apr 28 2009
Welcome. MLT:D is really an amazing language!<Yep.It really is everything that C++ did not manage to be, at least as far as my limited experience with it shows.<I also hope D will never be lot of the things C++ is, because C++ is too many things :-)1. struct vs. class As far as I understand, these two reserved words, that in C++ mean very similar things, in D are very different.<C++ classes are like structs, but their methods are private by default. In D structs have value semantics, are copied by value and keep the given order of the fields, while classes have reference semantics, are often allocated on the heap, and the compiler in theory can change the order of fields in memory. They are designed for different purposes, and I agree with such decision by But later practice has shown that you want struct constructors, and other things, so now D2 has them too. So structs are a bit closer to classes now in D2.A class variable is "really" a pointer, whereas a struct is directly allocated memory.<A class is a "reference". There are some ways manual or automatic with "scope" to sometimes allocate classes on the stack to improve performance. I have seen that sometimes it gives a nice speedup. You can't create an array of scoped classes by normal means, you have to manually change the way they allocate memory. Generally you can do what you want, but you may need some work to do special kinds of memory allocation.What I don't like is that it seems that structs and classes should almost be interchangeable - one might implement something as a class and later want it to be a struct, or vice versa. It almost is actually a local decision. I might want something to be a class in one place, and a struct in another.<In D they are by design different, because most of the times you want just one of the meanings.It seems to me that these are 3 different issues, and one should have control over them separately.<Giving control over each thing is of course nice and it may even increase performance in special situations. But it surely leads to an increase of the complexity of the language (and its use). D tries to be less complex than C++ (and C++ today is probably one of the most complex languages, and such very high complexity is now slowly killing it), and this means that sometimes you have to give up on some flexibility. If the language is well designed then most of the times, in practical programs, you don't feel much of such limitations.Otherwise, it seems to me that a program that uses both (struct and class) can get mightily confusing.<It's confusing if you are used to program in a language like Python, where everything acts according to a reference semantics (more or less, it's not exactly like that, it's a name-semantics). But D is more complex and powerful than Python, and lower level too, and it gives you both reference and data semantics. Once you know that, you just have to keep in memory that classes are by reference and structs are by values, and you can live well (you can also have pointer to structs. I think I have never used a pointer to class in D yet).Maybe the solution is to not use struct (which is I guess what is recommended unless you really need it.)<Structs are useful in D because classes have some overhead in both memory, and their methods are always virtual (and all the current D compilers are unable to devirtualize such methods, maybe not even GDC is able to do it, even if G++ is sometime able to devirtualize C++ virtual methods, I think it's the only C++ compiler able to do that)), and being usually allocated on the heap (D compilers aren't like HotSpot that is sometimes able to allocate classes on the stack when it is sure they not exit the scope) they aren't fit if you for example need small [x,y] vectors.2. char[] vs. int[] I think it is strange that char[] x = "1234" ; x[0] = '4' ; Produces a run time error, but int[] x = [1,2,3,4] ; x[0] = 4 ; Doesn't. I think that they both should, or both shouldn't - to be consistent (and it would be better if they both didn't).I leave this to other people. in D2 strings are immutable, by the way, while static arrays are not.Best would be again, to allow the programmer to specify where the array (or other stuff) should be stored.<That requires you to pay some complexity. And D designers/programmers may be unwilling to pay it.Given that, it is even sadder than it is in C++, that one can not inherit from the basic types.<Yes, this is a problem of D2. Scala language shows that there are better ways to design types, as you say. Walter has recently changed the D2 language to allow a bit of this, using "this". With that you can define a struct that behaves for example like the built-in associative array, and you don't need to redefine all its almost-methods. Bye, bearophile
Apr 28 2009
On Tue, 28 Apr 2009 13:00:36 -0400, bearophile <bearophileHUGS lycos.com> wrote:This has been discussed. Most people agree that the behavior should be consistent. Any array literal should be exactly that -- an unchangable literal. In D2, it should be an immutable literal (and produce a compile time error if you try and change it). BTW, this behavior you noticed is only on certain OSes. On other OSes (I think windows), you get weird behavior: char[] x = "1234"; x[0] = '4'; // no runtime error char[] y = "1234"; // y actually now equals "4234"! -SteveMLT: 2. char[] vs. int[] I think it is strange that char[] x = "1234" ; x[0] = '4' ; Produces a run time error, but int[] x = [1,2,3,4] ; x[0] = 4 ; Doesn't. I think that they both should, or both shouldn't - to be consistent (and it would be better if they both didn't).I leave this to other people. in D2 strings are immutable, by the way, while static arrays are not.
Apr 28 2009
Steven Schveighoffer Wrote:BTW, this behavior you noticed is only on certain OSes. On other OSes (I think windows), you get weird behavior: char[] x = "1234"; x[0] = '4'; // no runtime error char[] y = "1234"; // y actually now equals "4234"! -StevePretty nice. It would be even nicer if you had the following: char[] x = "1234"; x[0] = '4'; // no runtime error char[] y = "12"; // y now equals "42" ;)
Apr 28 2009
bearophile wrote:Yes, this is a problem of D2. Scala language shows that there are better ways to design types, as you say.Could you please give a little more detail? And speaking of Scala, after having watched a presentation, I was left with the impression that traits are nothing but classes with parameterized base. I mean this: abstract class Person { def schedule:Schedule } trait Student extends Person { private var classSchedule:Schedule = ... override def schedule = classSchedule def learn() = {...} } trait Worker extends Person { private var workSchedule:Schedule = ... override def schedule = workSchedule def work() = {...} } class CollegeStudent(school:School, company:Company) extends Student with Worker { // ... } is really this (in Scala-D made-up language): abstract class Person { def schedule:Schedule } class Student(Base) extends Person { private var classSchedule:Schedule = ... override def schedule = classSchedule def learn() = {...} } class Worker(Base) extends Person { private var workSchedule:Schedule = ... override def schedule = workSchedule def work() = {...} } class CollegeStudent(school:School, company:Company) extends Worker!(Student!(CollegeStudent)) { // ... } Is that correct? Andrei
Apr 28 2009
Andrei Alexandrescu:Could you please give a little more detail?My experience with Scala is near zero, I have written and compiled only small programs, like the ones from the Shootout and the ones of the first tutorial. Scala isn't a language as simple as they say, its type system is quite complex and powerful, so Scala isn't easy to learn if you want to use it well. You can use monads in Scala too, in a decent enough way: http://www.scala-lang.org/node/46 To give you a small answer, in Scala all types are used in a quite uniform way. This is useful. Even integers have a methods (as in Ruby, but Scala is statically compiled). You can add "methods" to all integers: object extendBuiltins extends Application { def fact(n: Int): BigInt = if (n == 0) 1 else fact(n-1) * n class Factorizer(n: Int) { def ! = fact(n) } implicit def int2fact(n: Int) = new Factorizer(n) println(10!) } Removing most of the distinction from built-in types and values and user-defined ones has some advantages. alias this of D2 is a little step in that direction. Like the idea of having first-class types. Once you have first-class types, with run-time-function-evaluation you may not need templates anymore. You have just functions that act on types that run at runtime too. The space of all possible computer languages is huge.And speaking of Scala, after having watched a presentation, I was left with the impression that traits are nothing but classes with parameterized base.[...]Is that correct?I don't know, I am sorry. I may be able to answer your question after reading the Scala docs, but you may do that yourself, and probably more efficiently, because you are smarter. Bye, bearophile
Apr 28 2009
On Tue, Apr 28, 2009 at 12:07 PM, MLT <none anon.com> wrote:What I don't like is that it seems that structs and classes should almost=be interchangeable - one might implement something as a class and later wa= nt it to be a struct, or vice versa. It almost is actually a local decision= . I might want something to be a class in one place, and a struct in anothe= r. I hear this all the time from C++ users. But in practice, it virtually never comes up. I have never, in my five years of using D, wanted to change a class to a struct or vice versa, or ever seen anyone else doing that (or complaining about its difficulty). The only people who complain are those who don't use the language ;)And, it seems that struct and class refer to several different things: (1=) struct and class are allocated in different places, (2) struct is suppose= d to ensure its structure, and (3) struct is copied by value, whereas class= by reference.It seems to me that these are 3 different issues, and one should have con=trol over them separately. Again, in practice, you will virtually always want *either* value semantics *or* polymorphism. In the few cases where you need both, you can imitate it with mixins and the like (and with D2, 'alias this' is nice).I find this example a bit strange: struct S { int x;} class C {int x;} void main() { { =A0S x ; =A0x.x =3D 1 ; =A0S y =3D x ; =A0y.x =3D2 ; =A0writefln(x.x) ; // x.x is 1 } { =A0C x =3D new C ; =A0x.x =3D 1; =A0C y =3D x ; =A0y.x =3D 2 ; =A0writefln(x.x) ; // x.x is 2 } } I would have preferred to declare directly that the variable y takes or d=oesn't take a reference when assigned. Otherwise, it seems to me that a pro= gram that uses both (struct and class) can get mightily confusing. Again, in practice, it doesn't :) You always use some types as values and others always as references. Are C programs that use both ints and char* s mighty confusing?Maybe the solution is to not use struct (which is I guess what is recomme=nded unless you really need it.) Please don't make everything a class. This isn't Java ;) What is instead recommended is that you use structs for value types and classes for everything else.
Apr 28 2009
Jarrett Billingsley wrote:On Tue, Apr 28, 2009 at 12:07 PM, MLT <none anon.com> wrote:Often I'd wish to statically allocate an object in the current context, like you can do with a struct. scope partially gives me what I want. It would be nice if "scope" could be used in other places: class Bla { int member; } class Foo { scope Bla b; //object constructed here } static assert(Foo.classinfo.init.size == 5*4); Yeah, you'd need a solution for how to call the ctor. Maybe the (very annoying) way of how initialization of final/const members is handled would be useful here.What I don't like is that it seems that structs and classes should almost be interchangeable - one might implement something as a class and later want it to be a struct, or vice versa. It almost is actually a local decision. I might want something to be a class in one place, and a struct in another.I hear this all the time from C++ users. But in practice, it virtually never comes up. I have never, in my five years of using D, wanted to change a class to a struct or vice versa, or ever seen anyone else doing that (or complaining about its difficulty). The only people who complain are those who don't use the language ;)
Apr 28 2009
On Tue, 28 Apr 2009 21:42:51 +0400, grauzone <none example.net> wrote:Jarrett Billingsley wrote:I belive it could be implemented as a library type, using Scope(T) template: class Foo { Scope!(Bar) _bar; } Perphaps, Phobos could provide that functionality, then we could deprecate "scope Foo foo = new Foo(args);" in favor of "auto foo = Scope!(Foo)(args);" and eventually remove from language.On Tue, Apr 28, 2009 at 12:07 PM, MLT <none anon.com> wrote:Often I'd wish to statically allocate an object in the current context, like you can do with a struct. scope partially gives me what I want. It would be nice if "scope" could be used in other places: class Bla { int member; } class Foo { scope Bla b; //object constructed here } static assert(Foo.classinfo.init.size == 5*4); Yeah, you'd need a solution for how to call the ctor. Maybe the (very annoying) way of how initialization of final/const members is handled would be useful here.What I don't like is that it seems that structs and classes should almost be interchangeable - one might implement something as a class and later want it to be a struct, or vice versa. It almost is actually a local decision. I might want something to be a class in one place, and a struct in another.I hear this all the time from C++ users. But in practice, it virtually never comes up. I have never, in my five years of using D, wanted to change a class to a struct or vice versa, or ever seen anyone else doing that (or complaining about its difficulty). The only people who complain are those who don't use the language ;)
Apr 28 2009
I belive it could be implemented as a library type, using Scope(T) template:I don't like that approach to replace random language features by templates at all. And in this case, you really have to ask WHY? It's nice that it's possible, but there are some reasons that speak against this approach: 1. it's harder to understand in general (even if the language definition becomes smaller) 2. error messages turn into an incomprehensible mess 3. puts more stress on the compiler and it gets slower (you will understand when you have to _wait_ for your project to finish compilation, even if you use the superfast dmd)class Foo { Scope!(Bar) _bar; }Would typeof(_bar) == Bar?Perphaps, Phobos could provide that functionality, then we could deprecate "scope Foo foo = new Foo(args);" in favor of "auto foo = Scope!(Foo)(args);" and eventually remove from language.
Apr 28 2009
On Tue, 28 Apr 2009 22:50:28 +0400, grauzone <none example.net> wrote:No way! But Scope!(Bar) would be implicitly castable to Bar (just not vice-versa): Bar b = _bar; // allowed _bar = b; // disallowed In fact, I don't like scope as it is: scope Foo foo = ...; // is foo scope allocated or not? It depends: scope Foo foo = new Foo(); // scope-allocated Foo getFoo() { return new Foo(); } scope Foo foo = getFoo(); // ???? In last example, DMD may inline and make it scope-allocated, but may not inline and make it heap-allocated. Scope!(Foo) foo = ...; gives you better control over allocation. For example, Scope!(Foo) foo = getFoo(); won't even compile.I belive it could be implemented as a library type, using Scope(T) template:I don't like that approach to replace random language features by templates at all. And in this case, you really have to ask WHY? It's nice that it's possible, but there are some reasons that speak against this approach: 1. it's harder to understand in general (even if the language definition becomes smaller) 2. error messages turn into an incomprehensible mess 3. puts more stress on the compiler and it gets slower (you will understand when you have to _wait_ for your project to finish compilation, even if you use the superfast dmd)class Foo { Scope!(Bar) _bar; }Would typeof(_bar) == Bar?
Apr 28 2009
Denis Koroskin wrote:...Scope stack-allocating is an optimisation. It doesn't guarantee it because that it's the point of scope. Given that you're hung-up about stack allocation, I can't imagine how you'd implement scope as a template. Hell, I can't imagine how you'd implement Scope as a template for *any* of its behaviours. class Foo { Scope!(Bar) _bar; } How do you guarantee deterministic destruction when it's inside a non-deterministic construct? -- Daniel
Apr 28 2009
On Wed, 29 Apr 2009 06:09:49 +0400, Daniel Keep <daniel.keep.lists gmail.com> wrote:Denis Koroskin wrote:Is that a challenge? import std.stdio; class Foo { this(int i, int j, int k) { writeln("Foo.this(): ", i, j, k); } ~this() { writeln("Foo.~this()"); } } struct Scope(T) { this(Args...)(Args args) { _data[] = T.classinfo.init[]; // shouldn't be needed __get.__ctor(args); } ~this() { __get.__dtor(); } alias __get this; T __get() { return cast(T)_data.ptr; } static assert(is(T == class)); private byte[__traits(classInstanceSize, T)] _data; //private byte[__traits(classInstanceSize, T)] _data = T.classinfo.init; // bug: doesn't work } void main() { auto foo = Scope!(Foo)(1, 2, 3); } One more bug-o-feature is that Scope.ctor is not called when args set is empty: auto foo = Scope!(Foo)(); // no Scope.__ctor is called and thus underlying Foo instance is left uninitialized. I never understood a rationale behind this "feature". I believe it's a hole....Scope stack-allocating is an optimisation. It doesn't guarantee it because that it's the point of scope. Given that you're hung-up about stack allocation, I can't imagine how you'd implement scope as a template. Hell, I can't imagine how you'd implement Scope as a template for *any* of its behaviours. class Foo { Scope!(Bar) _bar; } How do you guarantee deterministic destruction when it's inside a non-deterministic construct? -- Daniel
Apr 29 2009
Here is another example: import std.stdio; import Scope; class Foo { this(int i, int j, int k) { writeln("Foo.this(): ", i, j, k); } ~this() { writeln("Foo.~this()"); } } class Bar { this(int i, int j, int k) { writeln("Bar.this(): ", i, j, k); foo = Scope!(Foo)(i, j, k); } ~this() { writeln("Bar.~this()"); } Scope!(Foo) foo; } // Just for comparison - note that they are almost the same class NoScopeBar { this(int i, int j, int k) { writeln("NoScopeBar.this()"); foo = new Foo(i, j, k); } ~this() { writeln("NoScopeBar.~this()"); } Foo foo; } void main() { auto bar = Scope!(Bar)(1, 2, 3); } Expected output: Bar.this(): 123 Foo.this(): 123 Bar.~this() Foo.~this() Output: Bar.this(): 123 Foo.this(): 123 Bar.~this() It is a DMD bug: calling an object's dtor should call dtors on all its fields.
Apr 29 2009
On Wed, 29 Apr 2009 13:06:18 +0400, Denis Koroskin <2korden gmail.com> wrote:It is a DMD bug: calling an object's dtor should call dtors on all its fields.This could be temporarily worked around by little template magic: foreach(field; filterFields(__traits(allMembers,T))) { field.dtor(); }
Apr 29 2009
On Tue, Apr 28, 2009 at 6:07 PM, MLT <none anon.com> wrote:2. char[] vs. int[] I think it is strange that char[] x = "1234" ; x[0] = '4' ; Produces a run time error, but int[] x = [1,2,3,4] ; x[0] = 4 ; Doesn't. I think that they both should, or both shouldn't - to be consistent (and it would be better if they both didn't). Best would be again, to allow the programmer to specify where the array (or other stuff) should be stored.It pretty much boils down to this (mostly said in other replies) * string literals are special, they are allocated in a static data segment, readonly if the platform allows it. * arrayliterals as non-static expressions are always heap allocated. even when there's absolute no need for it... (see http://d.puremagic.com/issues/show_bug.cgi?id=2356 ) -Tomas
Apr 28 2009
On Tue, 28 Apr 2009 22:13:50 +0400, Tomas Lindquist Olsen <tomas.l.olsen gmail.com> wrote:On Tue, Apr 28, 2009 at 6:07 PM, MLT <none anon.com> wrote:Someone ought to post a feature request to make arrayliterals immutable by default (D2 only, I don't think this change will go to D1 anyway) and don't heap-allocate them every time they're used: int[] x1 = [1,2,3,4]; // error: can't assign immutable(int)[] to int[] int[] x2 = [1,2,3,4].dup; // okay, allocates int[4] x3 = [1,2,3,4]; // okay, doesn't allocate foreach (int i; [1,2,3,4]) { // okay, doesn't allocate // ... }2. char[] vs. int[] I think it is strange that char[] x = "1234" ; x[0] = '4' ; Produces a run time error, but int[] x = [1,2,3,4] ; x[0] = 4 ; Doesn't. I think that they both should, or both shouldn't - to be consistent (and it would be better if they both didn't). Best would be again, to allow the programmer to specify where the array (or other stuff) should be stored.It pretty much boils down to this (mostly said in other replies) * string literals are special, they are allocated in a static data segment, readonly if the platform allows it. * arrayliterals as non-static expressions are always heap allocated. even when there's absolute no need for it... (see http://d.puremagic.com/issues/show_bug.cgi?id=2356 ) -Tomas
Apr 28 2009
Denis Koroskin wrote:On Tue, 28 Apr 2009 22:13:50 +0400, Tomas Lindquist Olsen <tomas.l.olsen gmail.com> wrote:Why not auto-allocate? Writing that .dup all the time is going to be annoying. Just implicitly convert it from immutable to mutable by copying.On Tue, Apr 28, 2009 at 6:07 PM, MLT <none anon.com> wrote:Someone ought to post a feature request to make arrayliterals immutable by default (D2 only, I don't think this change will go to D1 anyway) and don't heap-allocate them every time they're used: int[] x1 = [1,2,3,4]; // error: can't assign immutable(int)[] to int[]2. char[] vs. int[] I think it is strange that char[] x = "1234" ; x[0] = '4' ; Produces a run time error, but int[] x = [1,2,3,4] ; x[0] = 4 ; Doesn't. I think that they both should, or both shouldn't - to be consistent (and it would be better if they both didn't). Best would be again, to allow the programmer to specify where the array (or other stuff) should be stored.It pretty much boils down to this (mostly said in other replies) * string literals are special, they are allocated in a static data segment, readonly if the platform allows it. * arrayliterals as non-static expressions are always heap allocated. even when there's absolute no need for it... (see http://d.puremagic.com/issues/show_bug.cgi?id=2356 ) -Tomasint[] x2 = [1,2,3,4].dup; // okay, allocates int[4] x3 = [1,2,3,4]; // okay, doesn't allocate foreach (int i; [1,2,3,4]) { // okay, doesn't allocate // ... }
Apr 28 2009
grauzone wrote:Denis Koroskin wrote:Definitely. They should go into the initialized data segment.On Tue, 28 Apr 2009 22:13:50 +0400, Tomas Lindquist Olsen <tomas.l.olsen gmail.com> wrote:On Tue, Apr 28, 2009 at 6:07 PM, MLT <none anon.com> wrote:Someone ought to post a feature request to make arrayliterals immutable by default (D2 only, I don't think this change will go to D1 anyway) and don't heap-allocate them every time they're used:2. char[] vs. int[] I think it is strange that char[] x = "1234" ; x[0] = '4' ; Produces a run time error, but int[] x = [1,2,3,4] ; x[0] = 4 ; Doesn't. I think that they both should, or both shouldn't - to be consistent (and it would be better if they both didn't). Best would be again, to allow the programmer to specify where the array (or other stuff) should be stored.It pretty much boils down to this (mostly said in other replies) * string literals are special, they are allocated in a static data segment, readonly if the platform allows it. * arrayliterals as non-static expressions are always heap allocated. even when there's absolute no need for it... (see http://d.puremagic.com/issues/show_bug.cgi?id=2356 ) -TomasI think it's pretty unlikely that you'd want to do that. It's far more likely that it's a bug, and you meant it to be an immutable(int)[]. Except in the case where the array is empty. (Likewise, it'd be nice if char [] s=""; were legal in D2. Since a mutable "" string has nothing that can be changed anyway, "" can be treated in the same way that 'null' is).int[] x1 = [1,2,3,4]; // error: can't assign immutable(int)[] to int[]Why not auto-allocate? Writing that .dup all the time is going to be annoying. Just implicitly convert it from immutable to mutable by copying.int[] x2 = [1,2,3,4].dup; // okay, allocates int[4] x3 = [1,2,3,4]; // okay, doesn't allocate foreach (int i; [1,2,3,4]) { // okay, doesn't allocate // ... }
Apr 29 2009
Don wrote:(Likewise, it'd be nice if char [] s=""; were legal in D2. Since a mutable "" string has nothing that can be changed anyway, "" can be treated in the same way that 'null' is).There was a huge discussion about null strings a few years ago. (Probably it was before Andrei, and possibly before your time.) IIRC, most of the discussion was about detecting the "nullness" of a string, and what we should define the Null string to be, there were a few good thoughts around the subject in general.
Apr 29 2009
On Wed, 29 Apr 2009 05:44:07 -0400, Don <nospam nospam.com> wrote:Except in the case where the array is empty. (Likewise, it'd be nice if char [] s=""; were legal in D2. Since a mutable "" string has nothing that can be changed anyway, "" can be treated in the same way that 'null' is).Why is this more desirable than just: char[] s; int[] i; Which works now. -Steve
Apr 29 2009