www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Re: struct vs. class

reply Martin <m_dot_hinsch rug.nl> writes:
Gregor Richards Wrote:

 Martin wrote:
 Inspired by the recent discussion about iterator structs/classes I wanted to
ask - what's the design rationale behind having both structs and classes? In
C++ the necessity was given by backwards compatibility but that doesn't apply
to D of course. 
 The only principal differences I can see (I'm not a D programmer (yet), so
please correct me if I'm wrong) are a) that structs don't contain run-time meta
information (a pointer to a vtable or however that works) and b) that struct
variables are statically allocated as opposed to class variables which always
seem to be pointers into dynamic memory.
 Somehow this looks really unorthogonal to me. Especially b) I find strange,
can somebody explain the reason for this?
 
 cheers
 Martin

Firstly, your assertion about C++ is incorrect. C++ doesn't have both, classes are just structs that are private by default, structs are just classes that are public by default.

Yes, I know that - still, formally they are two different things (albeit very similar).
 Structs in D are very light-weight. A struct is just a conglomeration of 
 data. Passing a struct which contains two ints is exactly like passing 
 the two ints, but syntactically less gross. Functions defined within a 

Isn't that the same as a tuple, then?
 struct are basically syntactic sugar around functions that are defined 
 taking the struct as the first argument.

Hmmm, but in principle the same holds for class functions. The only difference is that there is an additional lookup rule since they are virtual per default.
 Classes are properly object oriented: They have hierarchies, methods are 
 virtual, etc. As such, they're (comparably to structs) heavyweight: They 
 have classinfo, are allocated on the heap, method calls require looking 
 in a vtable, etc.
 

There is no reason why structs couldn't have hierarchies as well.
 Your 'b' statement is incorrect. In both cases, the data is allocated 
 where the struct/class is allocated. Just classes are usually on the 
 heap, structs are generally on the stack.
 

Anyways, my point is that really the only *necessary* difference between structs and classes is that the latter can have run-time type information and virtual functions. Everything else is just convenient syntactical sugar for which there is no technical reason to not add it to structs as well. And if that's the case I start to wonder if it's not possible to unify the two concepts somehow. cheers Martin
May 28 2007
next sibling parent reply Derek Parnell <derek psych.ward> writes:
On Mon, 28 May 2007 17:36:51 -0400, Martin wrote:

 Anyways, my point is that really the only *necessary* difference
 between structs and classes is that the latter can have run-time
 type information and virtual functions. Everything else is just
 convenient syntactical sugar for which there is no technical
 reason to not add it to structs as well.
 And if that's the case I start to wonder if it's not possible
 to unify the two concepts somehow.

They cannot and should not be 'unified' because their purpose is different. They serve different roles for the programmer. To quote the D documentation "Structs are meant as simple aggregations of data, or as a way to paint a data structure over hardware or an external type." Class objects contain at least two hidden data members which mean that they cannot be used to 'paint over RAM', to give structure to some data. See the ABI section of the docs ... An object consists of: --------*------------------ offset | contents --------+------------------ 0 | pointer to vtable ptrsize | monitor In other words an 'empty' object takes up 8 bytes (on a 32-bit machine) and an empty struct takes up zero bytes. -- Derek Parnell Melbourne, Australia "Justice for David Hicks!" skype: derek.j.parnell
May 28 2007
parent reply Martin <m_dot_hinsch rug.nl> writes:
Derek Parnell Wrote:

 On Mon, 28 May 2007 17:36:51 -0400, Martin wrote:
 
 Anyways, my point is that really the only *necessary* difference
 between structs and classes is that the latter can have run-time
 type information and virtual functions. Everything else is just
 convenient syntactical sugar for which there is no technical
 reason to not add it to structs as well.
 And if that's the case I start to wonder if it's not possible
 to unify the two concepts somehow.

They cannot and should not be 'unified' because their purpose is different. They serve different roles for the programmer. To quote the D documentation "Structs are meant as simple aggregations of data, or as a way to paint a data structure over hardware or an external type." Class objects contain at least two hidden data members which mean that they cannot be used to 'paint over RAM', to give structure to some data. See the ABI section of the docs ... An object consists of: --------*------------------ offset | contents --------+------------------ 0 | pointer to vtable ptrsize | monitor In other words an 'empty' object takes up 8 bytes (on a 32-bit machine) and an empty struct takes up zero bytes. -- Derek Parnell Melbourne, Australia "Justice for David Hicks!" skype: derek.j.parnell

I know, but the differences between structs and classes go far beyond that. In my opinion that wouldn't be necessary. Or put the other way around I think it would be much more elegant (and make D easier to learn) to have aggregate types, RTTI and value/reference semantics as three orthogonal concepts. C++ does that by using virtual vs. the default and pointers/references vs. values with all the associated problems but there might be a cleaner and nicer way without having to give up the flexibility.
May 29 2007
parent Hasan Aljudy <hasan.aljudy gmail.com> writes:
Martin wrote:
 C++ does that by using virtual vs. the
 default and pointers/references vs. values with all the associated
 problems but there might be a cleaner and nicer way without having to
 give up the flexibility.

That is why C++ sucks. I actually like the D solution .. specially having used Java before .. a language with NOTHING other than classes!! and C++ .. a language without "real" classes. D has the best "in the middle" solution.
May 29 2007
prev sibling next sibling parent reply Mike Parker <aldacron71 yahoo.com> writes:
Martin wrote:

 
 There is no reason why structs couldn't have hierarchies as well.
 
 Your 'b' statement is incorrect. In both cases, the data is allocated 
 where the struct/class is allocated. Just classes are usually on the 
 heap, structs are generally on the stack.

Anyways, my point is that really the only *necessary* difference between structs and classes is that the latter can have run-time type information and virtual functions. Everything else is just convenient syntactical sugar for which there is no technical reason to not add it to structs as well. And if that's the case I start to wonder if it's not possible to unify the two concepts somehow.

When you want POD (plain old data) objects, with or without methods to manipulate them, it is nice to not have the overhead associated with classes. It also would be a bit cumbersome to interface with C code if structs had all of the class overhead.
May 28 2007
parent janderson <askme me.com> writes:
Mike Parker wrote:
 Martin wrote:
 
 There is no reason why structs couldn't have hierarchies as well.

 Your 'b' statement is incorrect. In both cases, the data is allocated 
 where the struct/class is allocated. Just classes are usually on the 
 heap, structs are generally on the stack.

class variable on the stack. Anyways, my point is that really the only *necessary* difference between structs and classes is that the latter can have run-time type information and virtual functions. Everything else is just convenient syntactical sugar for which there is no technical reason to not add it to structs as well. And if that's the case I start to wonder if it's not possible to unify the two concepts somehow.

When you want POD (plain old data) objects, with or without methods to manipulate them, it is nice to not have the overhead associated with classes. It also would be a bit cumbersome to interface with C code if structs had all of the class overhead.

In c++ if you define a class without any virtual it effectively becomes a D struct, without the overhead. D takes this one step further I guess and allows the user enforce no virtuals. (Of course the other difference is that classes are passed by reference in D).
May 28 2007
prev sibling parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
Martin wrote:
 Gregor Richards Wrote:
 
 Martin wrote:
 Inspired by the recent discussion about iterator structs/classes I wanted to
ask - what's the design rationale behind having both structs and classes? In
C++ the necessity was given by backwards compatibility but that doesn't apply
to D of course. 
 The only principal differences I can see (I'm not a D programmer (yet), so
please correct me if I'm wrong) are a) that structs don't contain run-time meta
information (a pointer to a vtable or however that works) and b) that struct
variables are statically allocated as opposed to class variables which always
seem to be pointers into dynamic memory.
 Somehow this looks really unorthogonal to me. Especially b) I find strange,
can somebody explain the reason for this?

 cheers
 Martin

classes are just structs that are private by default, structs are just classes that are public by default.

Yes, I know that - still, formally they are two different things (albeit very similar).

And you can tell they're considered different things by the annoying fact that if you forward declare a type with the wrong one, the C++ compiler will generate an error. ----- class Foobulator; inline void function(Foobulator& fref) { . . . } ----- struct Foobulator { . . . }; ----- ==> Error Foobulator was declared as a class now it's a struct. grrr. I don't care which it is Mr. silly compiler! And you shouldn't either! All you need to know is that I can make a pointer to the darned thing! --bb
May 29 2007
parent reply James Dennett <jdennett acm.org> writes:
Bill Baxter wrote:
 Martin wrote:
 Gregor Richards Wrote:

 Martin wrote:
 Inspired by the recent discussion about iterator structs/classes I
 wanted to ask - what's the design rationale behind having both
 structs and classes? In C++ the necessity was given by backwards
 compatibility but that doesn't apply to D of course. The only
 principal differences I can see (I'm not a D programmer (yet), so
 please correct me if I'm wrong) are a) that structs don't contain
 run-time meta information (a pointer to a vtable or however that
 works) and b) that struct variables are statically allocated as
 opposed to class variables which always seem to be pointers into
 dynamic memory.
 Somehow this looks really unorthogonal to me. Especially b) I find
 strange, can somebody explain the reason for this?

 cheers
 Martin

both, classes are just structs that are private by default, structs are just classes that are public by default.

Yes, I know that - still, formally they are two different things (albeit very similar).

And you can tell they're considered different things by the annoying fact that if you forward declare a type with the wrong one, the C++ compiler will generate an error.

(No, but a non-C++ compiler might...)
 -----
    class Foobulator;
 
    inline void function(Foobulator& fref) {
       . . .
    }
 -----
    struct Foobulator {
       . . .
    };
 -----
 ==> Error Foobulator was declared as a class now it's a struct.
 
 grrr.  I don't care which it is Mr. silly compiler!  And you shouldn't
 either!  All you need to know is that I can make a pointer to the darned
 thing!

I know of only one compiler which fails to compile that, and it's a bug. It's perfectly valid C++ code, and has been for a long, long time. class Foobulator; is *exactly* equivalent to struct Foobulator; in standard C++. (Note the semi-colons on there, making these non-definitions.) -- James
May 29 2007
parent reply Bill Baxter <dnewsgroup billbaxter.com> writes:
James Dennett wrote:
 Bill Baxter wrote:
 Martin wrote:
 Gregor Richards Wrote:

 Martin wrote:
 Inspired by the recent discussion about iterator structs/classes I
 wanted to ask - what's the design rationale behind having both
 structs and classes? In C++ the necessity was given by backwards
 compatibility but that doesn't apply to D of course. The only
 principal differences I can see (I'm not a D programmer (yet), so
 please correct me if I'm wrong) are a) that structs don't contain
 run-time meta information (a pointer to a vtable or however that
 works) and b) that struct variables are statically allocated as
 opposed to class variables which always seem to be pointers into
 dynamic memory.
 Somehow this looks really unorthogonal to me. Especially b) I find
 strange, can somebody explain the reason for this?

 cheers
 Martin

both, classes are just structs that are private by default, structs are just classes that are public by default.

(albeit very similar).

fact that if you forward declare a type with the wrong one, the C++ compiler will generate an error.

(No, but a non-C++ compiler might...)
 -----
    class Foobulator;

    inline void function(Foobulator& fref) {
       . . .
    }
 -----
    struct Foobulator {
       . . .
    };
 -----
 ==> Error Foobulator was declared as a class now it's a struct.

 grrr.  I don't care which it is Mr. silly compiler!  And you shouldn't
 either!  All you need to know is that I can make a pointer to the darned
 thing!

I know of only one compiler which fails to compile that, and it's a bug. It's perfectly valid C++ code, and has been for a long, long time.

Hmm. Would that compiler be Microsoft Visual C++ 6.0?
 class Foobulator;
 
 is *exactly* equivalent to
 
 struct Foobulator;
 
 in standard C++.  (Note the semi-colons on there, making
 these non-definitions.)

Hey, you're right! I just tried it out in gcc. Works fine. And works for MSVC.NET 2003 too. And DMC too! Imagine that. I'll go sit in a corner now. --bb
May 29 2007
parent James Dennett <jdennett acm.org> writes:
Bill Baxter wrote:
 James Dennett wrote:
 Bill Baxter wrote:
 Martin wrote:
 Gregor Richards Wrote:

 Martin wrote:
 Inspired by the recent discussion about iterator structs/classes I
 wanted to ask - what's the design rationale behind having both
 structs and classes? In C++ the necessity was given by backwards
 compatibility but that doesn't apply to D of course. The only
 principal differences I can see (I'm not a D programmer (yet), so
 please correct me if I'm wrong) are a) that structs don't contain
 run-time meta information (a pointer to a vtable or however that
 works) and b) that struct variables are statically allocated as
 opposed to class variables which always seem to be pointers into
 dynamic memory.
 Somehow this looks really unorthogonal to me. Especially b) I find
 strange, can somebody explain the reason for this?

 cheers
 Martin

both, classes are just structs that are private by default, structs are just classes that are public by default.

(albeit very similar).

fact that if you forward declare a type with the wrong one, the C++ compiler will generate an error.

(No, but a non-C++ compiler might...)
 -----
    class Foobulator;

    inline void function(Foobulator& fref) {
       . . .
    }
 -----
    struct Foobulator {
       . . .
    };
 -----
 ==> Error Foobulator was declared as a class now it's a struct.

 grrr.  I don't care which it is Mr. silly compiler!  And you shouldn't
 either!  All you need to know is that I can make a pointer to the darned
 thing!

I know of only one compiler which fails to compile that, and it's a bug. It's perfectly valid C++ code, and has been for a long, long time.

Hmm. Would that compiler be Microsoft Visual C++ 6.0?

You named that tune in one.
 class Foobulator;

 is *exactly* equivalent to

 struct Foobulator;

 in standard C++.  (Note the semi-colons on there, making
 these non-definitions.)

Hey, you're right! I just tried it out in gcc. Works fine. And works for MSVC.NET 2003 too. And DMC too! Imagine that. I'll go sit in a corner now.

This corner's taken, I banished myself here after posting something naive on a SQLite mailing list earlier... -- James
May 29 2007