a[3} slower than a.x; a.z; a.z

I

Ioannis Vranos

JKop said:
Ron Natalie posted:

Gernot said:
Best of both worlds?


Is there a way of using "union" for this? Just out of curriosity. I
like [0] instead of .x
It's just as you are used to it.

Don't think so... You'd need some sort of anonymous struct which doesn't
exist in C++.


Thinking about that...

Let's say you had a load of code that defined anonymous structs throughout
(for instance, windows header files). Given the following definition:

union Blah
{
int k;

struct
{
int t;
float r;
};
};


(which I actually like, and I don't know why anonymous structs are
outlawed...)


Anonymous structs are not outlawed but are valid ISO C++ constructs when
used stand alone.
 
R

Ron Natalie

Anonymous structs are not outlawed but are valid ISO C++ constructs when
used stand alone.

No they are not (when using the term anonymous struct as an analog to
the legal C++ construct of anonymous union):

An anonymous union defines an unnamed object of unnamed type. If you
change union to struct, the program is ill-formed. All struct/class
key definitions must either define a named object or a named type.
 
I

Ioannis Vranos

Ron said:
No they are not (when using the term anonymous struct as an analog to
the legal C++ construct of anonymous union):

An anonymous union defines an unnamed object of unnamed type. If you
change union to struct, the program is ill-formed. All struct/class
key definitions must either define a named object or a named type.


Do you mean the following is not valid?



typedef struct
{
int i,k;
}AnonStruct;



class SomeClass { AnonStruct a; };


int main()
{
SomeClass r;

}
 
R

Ron Natalie

Ioannis said:
Do you mean the following is not valid?



typedef struct
{
int i,k;
}AnonStruct;

Nope that declares a type.

It does not meet the definition of "anonymous union" where you
change union to struct.
 
O

Old Wolf

Gernot Frisch said:
I was thinking additional memory used for alinging ia _always_
appended at the end of the structure, thus p_b == &blah.b. If not, I
really have to think about some code lines now...

No, there can be padding anywhere except for before the first
member. The ++p_b example is undefined behaviour anyway because
you are pointing beyond the bounds of the object 'a'.
A plausible example of this could be a 64-bit system with 32-bit
int but 64-bit alignment for int.
 
D

Dave Vandervies

No, there can be padding anywhere except for before the first
member. The ++p_b example is undefined behaviour anyway because
you are pointing beyond the bounds of the object 'a'.

Unless it's been changed from the C rules (and I don't see a good reason
why it would have been), creating a pointer to one past the end of an
array (where a single object[1] is considered as a one-element array)
is perfectly valid as long as you don't dereference it.

Not only that, but if you compare the result of incrementing p_b with
&(blah.b), they may be equal, and if they are you can use the pointer
as a pointer to p_b without any problems:

p_b=&(blah.a);
++p_b;
if(p_b==&(blah.b))
{
std::cout<<"No padding between Blah::a and Blah::b"<<std::endl;

//Using p_b like this is valid if and only if the control expression
// of the if evaluates to true
std::cout<<"blah.b is "<<*p_b<<std::endl;
}

A plausible example of this could be a 64-bit system with 32-bit
int but 64-bit alignment for int.

Plausible, but not terribly likely.
More likely (but still not all that likely for members of the same
struct) is aligning on a cache-line boundary (probably 128-byte, if
my vague recollection of a discussion of this I once saw is correct),
or even a memory-page boundary (4k?).


dave

[1] That's `object' in the C sense - basically a region of storage that
can contain a value
 
U

Unforgiven

Ioannis Vranos said:
Some things to mention:

1) Deterministic destruction / managed objects with stack semantics

2) All C++ features available for CLI types (e.g. templates). All CLI
features available in C++ (e.g. generics).


VC++ oriented:
3) More optimisation in the produced code. PGO optimisation.
4) More hand optimisation - OMP multithreading support

5) Ability to mix managed and unmanaged types freely, inherit managed
types from unmanaged, unmanaged from managed, unmanaged objects in the
managed heap, managed type objects in the native heap - VC++ support for
that in the release after 2005.

Add to that:
6) The C++ Linker can link in .Net Modules, meaning you can actually mix 'n
match different languages in the same assembly! With other .Net languages,
you can have different-language assemblies interoperate easily, but the C++
compiler linker is the only one that can create a single .Net assembly from
different language. This is mainly because the C# and VB.NET compilers have
no separate linking stage and the compiler does not accept .Net modules as
input.
C++/CLI: Correct by default.

Other languages (including C#/CLI): Correct by explicit coding

I don't really understand what you mean by "correct" here. Care to
elaborate?

Also, saying C#/CLI is nonsense, there is no C# without CLI so just saying
C# will do.
And as for .Net programming, I'm a VB.NET kinda guy. No matter how much I
love C++, I have much more experience in VB, and if I want to get something
done, I'm much, much more productive in VB.NET than in any other language.
Besides, Select Case over switch any day!
 
I

Ioannis Vranos

Unforgiven said:
I don't really understand what you mean by "correct" here. Care to
elaborate?


You can check the pdf or the ppt in the links that I posted.


Essentially it means that there is no need for Dispose() definitions in
C++/CLI but the compiler generates the Dispose from the Destructor that
you may define (including chaining calls to Dispose).


Copying from the pdf presentation:


1) Side By Side: Using a StreamReader

C++:

String^ ReadFirstLineFromFile( String^ path ) {
StreamReader r(path);
return r.ReadLine();
}


C#:

String ReadFirstLineFromFile( String path ) {
using ( StreamReader r = new StreamReader(path) ) {
return r.ReadLine();
}
}



Java:

String ReadFirstLineFromFile( String path ) {
StreamReader r = null;
String s = null;
try {
r = new StreamReader(path);
s = r.ReadLine();
} finally {
if ( r != null ) r.Dispose();
}
return s;
}




2) Side By Side: Using “lock”

C++:

{
lock l( obj );
… do something with shared state …
}


C#:

lock( obj ) {
… do something with shared state …
}


Java:

Monitor.Enter( obj );
try {
… do something with shared state …
} finally {
Monitor.Exit( obj );
}



3) Side By Side: Nontrivial “lock”

C++:

{
lock l( obj, 10 );
… do something with shared state …
}


C#:

if( !Monitor.TryEnter( obj, TimeSpan.FromSeconds( 10 ) ) ) {
throw new Something();
}
try {
… do something with shared state …
} finally {
Monitor.Exit( obj );
}


Java:

if( !Monitor.TryEnter( obj, TimeSpan.FromSeconds( 10 ) ) ) {
throw new Something();
}
try {
… do something with shared state …
} finally {
Monitor.Exit( obj );
}




4) Side By Side: Nontrivial “lock”


C++:

{
lock l( obj, 10 );
… do something with shared state …
}



C#:

using( new Lock( obj, 10 ) ) {
… do something with shared state …
}

public class Lock
: IDisposable {
private object target;
public Lock(
object o, double tm
) {
target = o;
if( !Monitor.TryEnter( o, tm ) )
throw new Something();
}

void IDisposable.Dispose() {

Monitor.Exit( target );

#if DEBUG

GC.SuppressFinalize( this );

#endif
}

#if DEBUG

~Lock() {

Diagnostics.Debug.Fail(
"Undisposed lock“
);

}

#endif

}

Also, saying C#/CLI is nonsense, there is no C# without CLI so just
saying C# will do.


The official standard is C#/CLI.
 

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

No members online now.

Forum statistics

Threads
473,778
Messages
2,569,605
Members
45,238
Latest member
Top CryptoPodcasts

Latest Threads

Top