Thread overview
Re: struct vs. class
May 28, 2007
Martin
May 28, 2007
Derek Parnell
May 29, 2007
Martin
May 29, 2007
Hasan Aljudy
May 29, 2007
Mike Parker
May 29, 2007
janderson
May 29, 2007
Bill Baxter
May 30, 2007
James Dennett
May 30, 2007
Bill Baxter
May 30, 2007
James Dennett
May 28, 2007
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.
> 
Oh, then I got that wrong. I thought there was no way in D to create a 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.

cheers
Martin
May 28, 2007
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 29, 2007
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.
>>
> Oh, then I got that wrong. I thought there was no way in D to create a 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.
May 29, 2007
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.
>>>
>> Oh, then I got that wrong. I thought there was no way in D to create a 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 29, 2007
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
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
>> 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).

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

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 30, 2007
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
>>> 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).
> 
> 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 30, 2007
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
>>>> 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).
>> 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.

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 30, 2007
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
>>>>> 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).
>>> 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.
> 
> 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