digitalmars.D - ctor for stucts?
- Kris (32/32) Nov 22 2005 I often use structs instead of classes, since one can instantiate them u...
- Hasan Aljudy (3/46) Nov 22 2005 I was under the impression that you can get the same effect by using an
- Kris (12/14) Nov 22 2005 Afraid not. That still involves the GC.
- Sean Kelly (9/23) Nov 22 2005 This is a side-effect of the "new" meaning of auto in D. The old
- Hasan Aljudy (12/42) Nov 22 2005 Who said it'll eventually be that?
- Jarrett Billingsley (9/11) Nov 23 2005 Then you run into the issue of the member arrangement. Sometimes you ne...
- John Reimer (5/48) Nov 22 2005 I don't have much to say, other than that I completely agree.
- Stewart Gordon (16/27) Nov 25 2005 I'm guessing that a struct invariant could solve part of this problem
- Stewart Gordon (13/22) Nov 25 2005 Correction: It seems that invariants are only called on entry or exit
- kris (7/35) Nov 25 2005 D doesn't currently support assignment at declaration for anything but
- Stewart Gordon (17/28) Nov 25 2005 It allows you to assign anything, constant or not, when declaring a
- kris (23/50) Nov 25 2005 You might not be able to use the suggested ctor at, for example, global
I often use structs instead of classes, since one can instantiate them upon the stack. It's great that D structs are just like classes in many ways. However, I often need to initialize the struct; just as one often needs to initialize a class before using it. I've taken to using opCall() to support such initialization, and I know that some folks have used static opCall() too. Unfortunately, the compiler does not generate an error where a user does not actually use the initializer. This can, obviously, lead to runtime failure. What I'd like to see is a true ctor (or plural) for structs ~ if present, it *must* be used. This would eliminate potential for some avoidable bugs: e.g. struct Foo { this (int a, char b) {} } void main() { Foo f; // compile-time error! Foo f (1, 'v'); // good! } I'm not advocating a struct dtor <g> ... suspect that may be unecessary. =================== Alternatively, the same effect could be realized by treating a static opCall() as a ctor instead: struct Bar { static opCall (char[] s) {} } void main() { Bar b; // compile-time error! Bar b ("doll"); // good! }
Nov 22 2005
Kris wrote:I often use structs instead of classes, since one can instantiate them upon the stack. It's great that D structs are just like classes in many ways. However, I often need to initialize the struct; just as one often needs to initialize a class before using it. I've taken to using opCall() to support such initialization, and I know that some folks have used static opCall() too. Unfortunately, the compiler does not generate an error where a user does not actually use the initializer. This can, obviously, lead to runtime failure. What I'd like to see is a true ctor (or plural) for structs ~ if present, it *must* be used. This would eliminate potential for some avoidable bugs: e.g. struct Foo { this (int a, char b) {} } void main() { Foo f; // compile-time error! Foo f (1, 'v'); // good! } I'm not advocating a struct dtor <g> ... suspect that may be unecessary. =================== Alternatively, the same effect could be realized by treating a static opCall() as a ctor instead: struct Bar { static opCall (char[] s) {} } void main() { Bar b; // compile-time error! Bar b ("doll"); // good! }I was under the impression that you can get the same effect by using an auto class with no dtor.
Nov 22 2005
"Hasan Aljudy" <hasan.aljudy gmail.com> wrote ...I was under the impression that you can get the same effect by using an auto class with no dtor.Afraid not. That still involves the GC. ============== BTW I noticed a subtle difference in the use of auto: class Bar {~this(){}} void main() { auto b = new Bar; // dtor not invoked auto Bar c = new Bar; // dtor always invoked; implicit try/catch } Thought that was worth noting, cos' it really is subtle given the implications.
Nov 22 2005
Kris wrote:BTW I noticed a subtle difference in the use of auto: class Bar {~this(){}} void main() { auto b = new Bar; // dtor not invoked auto Bar c = new Bar; // dtor always invoked; implicit try/catch } Thought that was worth noting, cos' it really is subtle given the implications.This is a side-effect of the "new" meaning of auto in D. The old meaning which indicates stack-based behavior will eventually be deprecated and replaced with a more value-oriented declaration syntax: Bar b = Bar(); // on stack Bar c = new Bar(); // on heap In the meantime, I'm afraid we're going to have to live with the confusing double-meaning of "auto." Sean
Nov 22 2005
Sean Kelly wrote:Kris wrote:Who said it'll eventually be that? Plus, I'd rather let the compiler decide where to put my object, IMO having to decide (or being given the choice) between stack and heap object kinda defies the point of using references and enforcing "new" on objects. I don't know if it's just me or what, but one of the confusing points about c++ is having the option of putting an object on the stack or on the heap, and using different syntax for each one, etc. I love how all objects in D are references, like Java!! If D starts to expose this low-level stuff to the programmer and give him options .. well let's just say that I feel it kills the point.BTW I noticed a subtle difference in the use of auto: class Bar {~this(){}} void main() { auto b = new Bar; // dtor not invoked auto Bar c = new Bar; // dtor always invoked; implicit try/catch } Thought that was worth noting, cos' it really is subtle given the implications.This is a side-effect of the "new" meaning of auto in D. The old meaning which indicates stack-based behavior will eventually be deprecated and replaced with a more value-oriented declaration syntax: Bar b = Bar(); // on stack Bar c = new Bar(); // on heapIn the meantime, I'm afraid we're going to have to live with the confusing double-meaning of "auto." Sean
Nov 22 2005
"Hasan Aljudy" <hasan.aljudy gmail.com> wrote in message news:dm00lq$2o0r$1 digitaldaemon.com...I was under the impression that you can get the same effect by using an auto class with no dtor.Then you run into the issue of the member arrangement. Sometimes you need the strict arrangement of a struct but still want to be able to use a ctor. An example would be with, say, a 3D vector that has x, y, and z components. These have to be kept in the correct order and need to be able to be passed to a graphics API which doesn't know about D (i.e. DirectX, OpenGL), but it would be nice to be able to write Vector v = Vector(5, 10, 15);
Nov 23 2005
Kris wrote:I often use structs instead of classes, since one can instantiate them upon the stack. It's great that D structs are just like classes in many ways. However, I often need to initialize the struct; just as one often needs to initialize a class before using it. I've taken to using opCall() to support such initialization, and I know that some folks have used static opCall() too. Unfortunately, the compiler does not generate an error where a user does not actually use the initializer. This can, obviously, lead to runtime failure. What I'd like to see is a true ctor (or plural) for structs ~ if present, it *must* be used. This would eliminate potential for some avoidable bugs: e.g. struct Foo { this (int a, char b) {} } void main() { Foo f; // compile-time error! Foo f (1, 'v'); // good! } I'm not advocating a struct dtor <g> ... suspect that may be unecessary. =================== Alternatively, the same effect could be realized by treating a static opCall() as a ctor instead: struct Bar { static opCall (char[] s) {} } void main() { Bar b; // compile-time error! Bar b ("doll"); // good! }I don't have much to say, other than that I completely agree. Unfortunately, struct ctors have been oft brought up here. I really wish that they were implemented. -JJR
Nov 22 2005
Kris wrote:I often use structs instead of classes, since one can instantiate them upon the stack. It's great that D structs are just like classes in many ways. However, I often need to initialize the struct; just as one often needs to initialize a class before using it. I've taken to using opCall() to support such initialization, and I know that some folks have used static opCall() too. Unfortunately, the compiler does not generate an error where a user does not actually use the initializer. This can, obviously, lead to runtime failure.I'm guessing that a struct invariant could solve part of this problem (though it would still be a runtime check). But as I try it (GDC 0.16), there seems to be a bug whereby struct invariants don't work at all.What I'd like to see is a true ctor (or plural) for structs ~ if present, it *must* be used. This would eliminate potential for some avoidable bugs: e.g.<snip> What would happen if you then try to use such a struct as a global variable or a member of a class or struct? Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:- C++ a->--- UB P+ L E W++ N+++ o K- w++ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++>++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Nov 25 2005
Stewart Gordon wrote:Kris wrote:<snip>Correction: It seems that invariants are only called on entry or exit from a member function, not on setting a member manually. Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:- C++ a->--- UB P+ L E W++ N+++ o K- w++ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++>++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.I've taken to using opCall() to support such initialization, and I know that some folks have used static opCall() too. Unfortunately, the compiler does not generate an error where a user does not actually use the initializer. This can, obviously, lead to runtime failure.I'm guessing that a struct invariant could solve part of this problem (though it would still be a runtime check). But as I try it (GDC 0.16), there seems to be a bug whereby struct invariants don't work at all.
Nov 25 2005
Stewart Gordon wrote:Kris wrote:D doesn't currently support assignment at declaration for anything but constant data. When that changes, down the road, it would presumably support the condition you note? Alternatively, you might be indicating that the construction should be delayed? If so, then don't put a ctor in the struct. It would operate in the same two phase (init + setup) approach as it does today?I often use structs instead of classes, since one can instantiate them upon the stack. It's great that D structs are just like classes in many ways. However, I often need to initialize the struct; just as one often needs to initialize a class before using it. I've taken to using opCall() to support such initialization, and I know that some folks have used static opCall() too. Unfortunately, the compiler does not generate an error where a user does not actually use the initializer. This can, obviously, lead to runtime failure.I'm guessing that a struct invariant could solve part of this problem (though it would still be a runtime check). But as I try it (GDC 0.16), there seems to be a bug whereby struct invariants don't work at all.What I'd like to see is a true ctor (or plural) for structs ~ if present, it *must* be used. This would eliminate potential for some avoidable bugs: e.g.<snip> What would happen if you then try to use such a struct as a global variable or a member of a class or struct? Stewart.
Nov 25 2005
kris wrote: <snip>It allows you to assign anything, constant or not, when declaring a local variable. Just not in other circumstances. Would changing this really be easy to implement, and can it be done without leading to confusing or undefined behaviour when initialisers may depend on each other?What would happen if you then try to use such a struct as a global variable or a member of a class or struct? Stewart.D doesn't currently support assignment at declaration for anything but constant data. When that changes, down the road, it would presumably support the condition you note?Alternatively, you might be indicating that the construction should be delayed? If so, then don't put a ctor in the struct. It would operate in the same two phase (init + setup) approach as it does today?So (for now at least) if you put a constructor in a struct, it'll become illegal to declare one except at function level? Stewart. -- -----BEGIN GEEK CODE BLOCK----- Version: 3.1 GCS/M d- s:- C++ a->--- UB P+ L E W++ N+++ o K- w++ O? M V? PS- PE- Y? PGP- t- 5? X? R b DI? D G e++>++++ h-- r-- !y ------END GEEK CODE BLOCK------ My e-mail is valid but not my primary mailbox. Please keep replies on the 'group where everyone may benefit.
Nov 25 2005
Stewart Gordon wrote:kris wrote: <snip>You might not be able to use the suggested ctor at, for example, global scope, if you don't already have the arguments to pass to it. Conceptually, the syntax might be something like this: struct Foo { this (int a, char b) {} } Foo foo(1, 'd'); From purely a dependency standpoint, this is no different that class construction. Do you have another approach? The problem is ensuring the struct is correctly initialised, and only when that is needed, using a convenient syntax. The invarient thing, whilst indeed useful, does not really address the latter. ============== To illustrate the current situation: struct Foo { void ctor(int a, char b) {} } Foo foo; foo.ctor (1, 'd');It allows you to assign anything, constant or not, when declaring a local variable. Just not in other circumstances. Would changing this really be easy to implement, and can it be done without leading to confusing or undefined behaviour when initialisers may depend on each other?What would happen if you then try to use such a struct as a global variable or a member of a class or struct? Stewart.D doesn't currently support assignment at declaration for anything but constant data. When that changes, down the road, it would presumably support the condition you note?Alternatively, you might be indicating that the construction should be delayed? If so, then don't put a ctor in the struct. It would operate in the same two phase (init + setup) approach as it does today?So (for now at least) if you put a constructor in a struct, it'll become illegal to declare one except at function level?
Nov 25 2005