C++ vs. C#

T

tonytech08

It's not really nitpicking this time.  C++ and C# have radically
different object models, and trying apply the languages
supported distinctions made by C# to C++ doesn't apply.  The
important point (which I do think you made), of course, is that
for all of the categories in C#, you can effectively do the same
thing with a class type in C++;
C# doesn't support anything that C++ doesn't.

Explicit layout control.
 
T

tonytech08

Probably... hang on...  Here's a good jumping off point:
http://msdn.microsoft.com/en-us/library/aa288471(VS.71).aspx.
It's the tutorial on C# structs. Note the "StructLayoutAttribute
Class" under "Further Reading". I'm not promoting that as a suggested
implementation, but rather pointing out that layout control is
important sometimes and that C# recognizes (and is able to "exploit"
it) that also.

[layout control] supposedly serves two purposes:
- emulating C/C++ unions
- interfacing with native code

Those were just 2 examples they gave. Surely they thought that the
obviousness didn't warrant any simpler examples.
 
T

tonytech08

You have to do better than saying "look up the C#
documentation".  I didn't find any definition of
"lightweight".  But the way this word is used suggests that
Microsoft likes to call value types "lightweight":

Unlike C++, C# very definitely divides what C++ calls "class
types" into three categories: structs, which have value
semantics and a language defined copy assignment operator,
classes, which have reference semantics and do not support
assignment, and interfaces, which can only be used as a base
class for one of the other two.  All three categories are easily
emulated in C++, and a typical application will use all
three---what C# calls [structs] are more often called entity types.

In C#, one can derive from an interface and still have a lightweight
class whereas doing the same derivation in C++ results in a
heavyweight class.
 
B

Bo Persson

tonytech08 said:
Explicit layout control.

Now we are back to the fact that C# only runs on the .NET platform,
and therefore can document the exact layout of the underlying data.
C++ wants to be more flexible, to allow implementations to target
other kinds of platforms.

Is this flexibility really an advantage or a disadvantage? :)


A similar example is C99 which has a typedef int32_t for those
platforms where this is possible, and lacks this typedef for platforms
where it is not possible. C# only targets platforms where an int32_t
type is possible. Does that make it a better language?!


Bo Persson
 
S

SG

It's not really nitpicking this time.  C++ and C# have radically
different object models, and trying apply the languages
supported distinctions made by C# to C++ doesn't apply.

I thought I made it clear that I'm only talking about the value/
reference semantics aspect.

Cheers!
SG
 
E

Erik Wikström

I obviously don't know what you are talking about and I'm guessing
I'm not the only one. So in case you want this thread to have any
responses that are worth reading you might want to reconsider
explaining yourself (w.r.t. lightweight concept) "again" or at least
point to some resource containing the definitions you use.
At this point, after having read up on C#'s usage of the
terminology, I'll refer the reader there. While it's not
necessarily my take or whole take on the concept, it should
suffice to introduce the unitiated. Look at the C#
documentation for the definition that MS gives to 'struct',
'class' and note the use of the term 'lightweight'.
You have to do better than saying "look up the C#
documentation". I didn't find any definition of
"lightweight". But the way this word is used suggests that
Microsoft likes to call value types "lightweight":

Unlike C++, C# very definitely divides what C++ calls "class
types" into three categories: structs, which have value
semantics and a language defined copy assignment operator,
classes, which have reference semantics and do not support
assignment, and interfaces, which can only be used as a base
class for one of the other two. All three categories are easily
emulated in C++, and a typical application will use all
three---what C# calls [structs] are more often called entity types.

In C#, one can derive from an interface and still have a lightweight
class whereas doing the same derivation in C++ results in a
heavyweight class.

Of course, because either you have a variable of the struct-type in
which case you know at compile-time that the object supports the
interface derived from. Or you box the struct (allocate memory on the
heap, generate a vptr, and all that stuff) at which point it works just
like a C++ class with virtual functions.

While the struct might seem quite lightweight from a programming
perspective you should be aware that when boxing comes into play it is
quite heavyweight for the implementation/application. If you find
yourself in a situation where you need to do a lot of boxing/unboxing
you should probably use a class instead of a struct, it will make things
much faster.
 
T

Thomas J. Gritzan

tonytech08 said:
Explicit layout control.

That's wrong. In C# you don't have control over the layout of classes or
structs, you have control over the marshalled representation.

You can do the same in C++, you would only have to code it yourself (or
use a library).
 
G

Grizlyk

Now we're talkin!!

Take in account, that you can not write any program, that will be
successfully executed on "125W quad core monster" and on "toaster", at
least there are no useful programs like this.

There is no easy way to unify hardware, but in general (undepended
from any language) case, there is a way to be portable and to be
compiled exactly to hardware simultaneously. To do it your program
must not refer to hardware directly, but refer to abstract types from
levels of portabibity, for example:

//exactly 16 bit of memory
typename int_p16
- in systems where CPU can not use the cluster compiler will do slow
runtime workaround
- useful for binary protability between different hardware

//at least 16 bit of memory
typename int_u16
- in systems where CPU can not use the clusters compiler will extend
memory up to nearest CPU block, if there is no the block compiler will
do slow runtime workaround
- useful to keep data range with fast CPU access

//fastest CPU block
typename int
- can be usless type due to overhead or overflow

And so on. While programming, you need to select correct type. The
problem of "only one type to select" can be resolved by object-
oriented methods.
It is evidently, some even low-level properties of C++ mus be
improved, but this is not easy to do.

grizlyk
 
T

tonytech08

Now we are back to the fact that C# only runs on the .NET platform,
and therefore can document the exact layout of the underlying data.
C++ wants to be more flexible, to allow implementations to target
other kinds of platforms.

Is this flexibility really an advantage or a disadvantage?  :)

A similar example is C99 which has a typedef int32_t for those
platforms where this is possible, and lacks this typedef for platforms
where it is not possible. C# only targets platforms where an int32_t
type is possible. Does that make it a better language?!

At least it tries to reach for the ideal and improve things rather
than "that's just the way things are" (however bizarre that may sound
to anyone).
 
T

tonytech08

I obviously don't know what you are talking about and I'm guessing
I'm not the only one. So in case you want this thread to have any
responses that are worth reading you might want to reconsider
explaining yourself (w.r.t. lightweight concept) "again" or at least
point to some resource containing the definitions you use.
At this point, after having read up on C#'s usage of the
terminology, I'll refer the reader there. While it's not
necessarily my take or whole take on the concept, it should
suffice to introduce the unitiated. Look at the C#
documentation for the definition that MS gives to 'struct',
'class' and note the use of the term 'lightweight'.
You have to do better than saying "look up the C#
documentation".  I didn't find any definition of
"lightweight".  But the way this word is used suggests that
Microsoft likes to call value types "lightweight":
Unlike C++, C# very definitely divides what C++ calls "class
types" into three categories: structs, which have value
semantics and a language defined copy assignment operator,
classes, which have reference semantics and do not support
assignment, and interfaces, which can only be used as a base
class for one of the other two.  All three categories are easily
emulated in C++, and a typical application will use all
three---what C# calls [structs] are more often called entity types.
In C#, one can derive from an interface and still have a lightweight
class whereas doing the same derivation in C++ results in a
heavyweight class.

Of course, because either you have a variable of the struct-type in
which case you know at compile-time that the object supports the
interface derived from. Or you box the struct (allocate memory on the
heap, generate a vptr, and all that stuff) at which point it works just
like a C++ class with virtual functions.

While the struct might seem quite lightweight from a programming
perspective you should be aware that when boxing comes into play it is
quite heavyweight for the implementation/application. If you find
yourself in a situation where you need to do a lot of boxing/unboxing
you should probably use a class instead of a struct, it will make things
much faster.

I don't have a handle on the MS terminology "box/unboxing" yet (last
week I thought I did, but obviously I didn't put it in long term
memory, maybe because it seemed like somthing dumb). I'm not sure that
it doesn't have to do with the rather curious decision to make structs
stack-only things and classes heap-only things. (Which further
obfuscates the lightweight/heavyweight designations).
 
T

tonytech08

tonytech08 schrieb:







That's wrong. In C# you don't have control over the layout of classes or
structs, you have control over the marshalled representation.

I don't think that is correct (but I can't refute it either). If C#
indeed operates within a VM, then as long as you stay in it, I think
you have that layout control. It's only when you bounce out of it that
you lose the guarantees. (?).
 
T

tonytech08

Take in account, that you can not write any program, that will be
successfully executed on "125W quad core monster" and on "toaster", at
least there are no useful programs like this.


There is no easy way to unify hardware, but in general (undepended
from any language) case, there is a way to be portable and to be
compiled exactly to hardware simultaneously. To do it your program
must not refer to hardware directly, but refer to abstract types from
levels of portabibity, for example:

//exactly 16 bit of memory
typename int_p16
- in systems where CPU can not use the cluster compiler will do slow
runtime workaround
- useful for binary protability between different hardware

//at least 16 bit of memory
typename int_u16
- in systems where CPU can not use the clusters compiler will extend
memory up to nearest CPU block, if there is no the block compiler will
do slow runtime workaround
-  useful to keep data range with fast CPU access

//fastest CPU block
typename int
- can be usless type due to overhead or overflow

And so on. While programming, you need to select correct type. The
problem of "only one type to select" can be resolved by object-
oriented methods.


It is evidently, some even low-level properties of C++ mus be
improved, but this is not easy to do.

grizlyk

I think I can say it much more concisely if I grok'd your post
overall:

People don't program to a standard (such as std C++), they program to
a platform. (Yes, yes, if you're a masochist, you decide that you will
target ALL platforms with one codebase and in doing so you will find
the holy grail of "portability").
 
T

Thomas J. Gritzan

tonytech08 said:
I don't think that is correct (but I can't refute it either). If C#
indeed operates within a VM, then as long as you stay in it, I think
you have that layout control. It's only when you bounce out of it that
you lose the guarantees. (?).

You can only specify object layout, when you pass these objects to
unmanaged code. When you call an unmanaged function, the VM copies C#
structs to another place (marshalled to the specified representation)
and pass the copies to the function.
It's written in the docs:

"Controls the layout of an object when exported to unmanaged code."

"The members of the object are laid out sequentially, in the order in
which they appear when exported to unmanaged memory."

http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.layoutkind.aspx

"This attribute is used [...] to specify the offset of each non- static
or constant member within the unmanaged representation of that class or
structure."
http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.fieldoffsetattribute.aspx

Or do you know other ways of control C# struct layout?
 
T

tonytech08

I don't think that is correct (but I can't refute it either). If C#
indeed operates within a VM, then as long as you stay in it, I think
you have that layout control. It's only when you bounce out of it that
you lose the guarantees. (?).

You can only specify object layout, when you pass these objects to
unmanaged code. When you call an unmanaged function, the VM copies C#
structs to another place (marshalled to the specified representation)
and pass the copies to the function.
It's written in the docs:

"Controls the layout of an object when exported to unmanaged code."

"The members of the object are laid out sequentially, in the order in
which they appear when exported to unmanaged memory."

http://msdn.microsoft.com/en-us/library/system.runtime.interopservice...

"This attribute is used [...] to specify the offset of each non- static
or constant member within the unmanaged representation of that class or
structure."http://msdn.microsoft.com/en-us/library/system.runtime.interopservice...

Or do you know other ways of control C# struct layout?


http://msdn.microsoft.com/en-us/lib...ropservices.structlayoutattribute(VS.71).aspx

I'm not a C# user though.
 
G

Grizlyk

I think I can say it much more concisely if I grok'd your post
overall:

People don't program to a standard (such as std C++), they program to
a platform. (Yes, yes, if you're a masochist, you decide that you will
target ALL platforms with one codebase and in doing so you will find
the holy grail of "portability").

What? Speak easy in english, who will translate all of these? I guess
only, that you do not like masochists. This is interesting, but what
about "must not refer to hardware directly"?

If wou will hide hardware by abstract types you will get "ALL
platforms with one codebase".
 
T

Thomas J. Gritzan

tonytech08 said:
"Controls the layout of an object when exported to unmanaged code."

"The members of the object are laid out sequentially, in the order in
which they appear when exported to unmanaged memory."

http://msdn.microsoft.com/en-us/library/system.runtime.interopservice...

"This attribute is used [...] to specify the offset of each non- static
or constant member within the unmanaged representation of that class or
structure."http://msdn.microsoft.com/en-us/library/system.runtime.interopservice...

Or do you know other ways of control C# struct layout?


http://msdn.microsoft.com/en-us/lib...ropservices.structlayoutattribute(VS.71).aspx

I'm not a C# user though.

But you do know, that StructLayoutAttribute is used together with
LayoutKind (my first link) and FieldOffsetAttribute (my second link),
don't you?

They all are part of the InteropServices namespace, which suggest that
they are made to support interoperability with other languages / non
..NET code.

Since all of it doesn't belong to the language C# but to the .NET
framework, you can do the same with Visual Basic or C++/CLI.

As with C++, the memory layout is not a language issue. The platform
defines the memory layout. Every C++ compiler has extensions to affect
the memory layout of objects to some extent. But when do you need to
control it explicitly? If you need your data in a specific format, you
can serialize it, as everyone else does.
 
T

tonytech08

What? Speak easy in english,

I do.
who will translate all of these?

What needs translation?
I guess
only, that you do not like masochists. This is interesting, but what
about "must not refer to hardware directly"?

I wasn't the one who wrote "must not refer to hardware directly".
If wou will hide hardware by abstract types you will get "ALL
platforms with one codebase".

You are erroneously taking two posters posts and combining them.
 
T

tonytech08

[about explicit memory layout]




"Controls the layout of an object when exported to unmanaged code."
"The members of the object are laid out sequentially, in the order in
which they appear when exported to unmanaged memory."
http://msdn.microsoft.com/en-us/library/system.runtime.interopservice....
"This attribute is used [...] to specify the offset of each non- static
or constant member within the unmanaged representation of that class or
structure."http://msdn.microsoft.com/en-us/library/system.runtime.interopservice...
Or do you know other ways of control C# struct layout?

I'm not a C# user though.

But you do know, that StructLayoutAttribute is used together with
LayoutKind (my first link) and FieldOffsetAttribute (my second link),
don't you?

They all are part of the InteropServices namespace, which suggest that
they are made to support interoperability with other languages / non
.NET code.

Since all of it doesn't belong to the language C# but to the .NET
framework, you can do the same with Visual Basic or C++/CLI.

As with C++, the memory layout is not a language issue. The platform
defines the memory layout. Every C++ compiler has extensions to affect
the memory layout of objects to some extent. But when do you need to
control it explicitly? If you need your data in a specific format, you
can serialize it, as everyone else does.

Serialization should not be necessary (and indeed it isn't, but it's
more pervasive than it should be because of layout issues for one
thing).
 
T

tonytech08

What? Speak easy in english, who will translate all of these? I guess
only, that you do not like masochists. This is interesting, but what
about "must not refer to hardware directly"?

If wou will hide hardware by abstract types you will get "ALL
platforms with one codebase".

OK, I think I know what you meant now.

I was saying: that the C++ language doesn't address portability
concerns other than by providing the standard library. (Do you have
threads available? 64-bit integers? IEEE floating point? Little
endian? Struct layout control? Etc.) Rather it leaves that as an
exercise for the developer to do. Given that, the developer will find
that chore of creating some kind of portability layer (and that
doesn't necessarily mean, nor primarily mean, "finding abstractions")
easier if he defines fewer target platforms (Wintel, for example)
rather than playing the "gotta be portable everywhere game" (a.k.a,
"searching for the holy grail of portability") which is
"massochistic". The developer programs to a higher level (the target
platform set) via the portability layer rather than just using raw C++
("the standard").
 
G

google

You can only specify object layout, when you pass these objects to
unmanaged code. When you call an unmanaged function, the VM copies C#
structs to another place (marshalled to the specified representation)
and pass the copies to the function.

The following program outputs 34567800 which would suggest that the
object layout is in effect in managed code as well:

[StructLayout(LayoutKind.Explicit)]
struct ExplicitType
{
[FieldOffset(0)]
public uint i1;
[FieldOffset(1)]
public uint i2;
}

class Program
{
static void Main()
{
ExplicitType o = new ExplicitType();
o.i2 = 0x12345678;
Console.WriteLine("{0:x}", o.i1);
}
}

Also see the IL:

..method private hidebysig static void Main() cil managed
{
.entrypoint
.maxstack 2
.locals init (
[0] valuetype InternalTestConsoleApplication1.ExplicitType o)
L_0000: ldloca.s o
L_0002: initobj InternalTestConsoleApplication1.ExplicitType
L_0008: ldloca.s o
L_000a: ldc.i4 0x12345678
L_000f: stfld uint32
InternalTestConsoleApplication1.ExplicitType::i2
L_0014: ldstr "{0:x}"
L_0019: ldloca.s o
L_001b: ldfld uint32
InternalTestConsoleApplication1.ExplicitType::i1
L_0020: box uint32
L_0025: call void [mscorlib]System.Console::WriteLine(string,
object)
L_002a: ret
}

Regards,
Anders Dalvander
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,769
Messages
2,569,582
Members
45,057
Latest member
KetoBeezACVGummies

Latest Threads

Top