Daddy's Technology Notes

Read, think, and write down the notes.

Thursday, November 10, 2005

dynamic_cast vs static_cast in managed c++

Pointer casting managed c++

static_cast is used for all conversions that are well-defined. These include “safe” conversions that the compiler would allow you to do without a cast and less-safe conversions that are nonetheless welldefined. The types of conversions covered by static_cast include typical castless conversions, narrowing (information-losing) conversions, forcing a conversion from a void*, implicit type conversions, and static navigation of class hierarchies.

C++ provides a special explicit cast (introduced in Chapter 3) called dynamic_cast that is a type-safe downcast operation. When you use dynamic_cast to try to cast down to a particular type, the return
value will be a pointer to the desired type only if the cast is proper and successful, otherwise it will return zero to indicate that this was not the correct type.
It is extremely important for the garbage collector to track all pointers into the common language runtime heap during program execution. This leads to the following constraint on __gc pointer casts.

Constraint

  • A __gc pointer shall not be cast to a __nogc pointer.
Example

// __gc_pointer10.cpp
// compile with: /clr
#using <mscorlib.dll>
__gc struct G { int i; };

int main() {
G *pG = new G;
int *pi;
pi = &pG->i; // C2440
pi = (int*)&pG->i; // C2440
}

It is possible to convert a __gc pointer to a __nogc pointer via pinning.

The Managed Extensions maintain the usual meanings of the various styles of C++ casts, limiting them somewhat to preserve the integrity of the common language runtime garbage collector. The following sections describe the impact on the Managed Extensions for each style of cast.


Pinning Pointers

An object or sub-object of a managed class can be pinned, in which case the common language runtime will not move it during garbage collection. The principal use of this is to pass a pointer to managed data as an actual parameter of an unmanaged function call.

A local variable called a pinning pointer can be declared whose top-level pointer type is qualified by the __pin keyword. During a collection cycle, the runtime will inspect the metadata created for the pinning pointer and will not move the item it points to.

Example

// __gc_pointer16.cpp
// compile with: /clr /EHsc
#using <mscorlib.dll>
#include <iostream>
__gc class G {
public:
int i;
G() { i = 0; };
};

class H {
public:
void incr(int * i) { // unmanaged function
(*i)++;
std::cout << *i << std::endl;
};
};

int main() {
G __pin * pG = new G; // pG is a pinning pointer
H * h = new H;
h->incr(& pG -> i); // pointer to managed data passed as actual
// parameter of unmanaged function call
}

Output

1

A pinned object is pinned only while a pinning pointer points to it. It is no longer pinned when its pinning pointer goes out of scope, or is set to 0 in the program. After that, any unmanaged pointers that remain pointing to that object must not be dereferenced. An unpinned item can be moved in the heap by the garbage collector. Any __nogc pointers that still point to it will not be updated, and dereferencing one of them could raise an unrecoverable exception.

Example

// __gc_pointer17.cpp
// compile with: /clr /LD
#using <mscorlib.dll>
__gc class G {
public:
int i;
};

void f(G * pG) {
G __pin* ppG = pG;
// the object pointed to by pG is pinned until the pinning
// variable ppG goes out of scope,
ppG = 0; // or is set to 0
}

A pinning pointer is volatile by default. It is redundant but not an error if the user declares a pinning pointer to be volatile. This prevents the optimizer from deleting an assignment of 0 to a pinning pointer in the source code, even though the assignment appears to be dead code.

Pinning a sub-object defined in a managed object has the effect of pinning the entire object. For example, if any element of an array is pinned, then the whole array is also pinned. There are no extensions to the language for declaring a pinned array. To pin an array, declare a pinning pointer to its element type, and pin one of its elements.

Example

// __gc_pointer18.cpp
// compile with: /clr
#using <mscorlib.dll>
#include <stdio.h>
using namespace System;
int main() {
Byte arr[] = new Byte[4]; // arr is a managed array
arr[0] = 'C';
arr[1] = '+';
arr[2] = '+';
arr[3] = '0';
Byte __pin * p = &arr[1]; // entire array is now pinned
unsigned char * cp = p;
printf("%s\n", cp); // bytes pointed at by cp will not move during call
}

Output

++0

Characteristics

  • A pinning pointer can be implicitly converted to a __nogc pointer.
This is the only mechanism provided for passing addresses in the common language runtime heap to functions expecting __nogc pointers. The primary use for this is passing such addresses to unmanaged functions in external DLLs.

Constraints

  • A pinning variable shall be a nonstatic local variable.
Except for its pinning properties, a pinning pointer is identical to a __gc pointer.
  • Two function overloads shall not differ only by the use of pin and __gc pointer types.
  • A pinning pointer type shall not be used in a cast expression. It can only be used to declare a variable.
Example

// __gc_pointer19.cpp
// compile with: /clr
#using <mscorlib.dll>
using namespace System;
__gc struct G { int i; };

int main() {
Object *o = new G;
if ( G __pin *pG = dynamic_cast<G __pin *>(o) ) { // C3834
pG->i = 10;
}
}

  • A pinning pointer can be implicitly converted to a __gc pointer.
Example

// __gc_pointer20.cpp
// compile with: /clr /LD
#using <mscorlib.dll>
__gc class G {
public:
int i;
};

void f(G * pG) {
G __pin * ppG = pG;
G * pG2 = ppG; // ok
};

  • A __nogc pointer can be converted to a pinning pointer only if the pinning pointer is an interior __gc pointer.
Example

// __gc_pointer21.cpp
// compile with: /clr
#using <mscorlib.dll>
struct G { int i; };
__gc struct H { int j; };
int main() {
G * g = new G; // g is a __nogc whole object pointer
H * h = new H;
int __pin * k = & h -> j; // k is a pinning interior __gc pointer
int * l = & g -> i; // l is a __nogc pointer
k = l; // ok
};


dynamic_cast

The use of dynamic_cast is prevalent in managed code. The common language runtime base class library uses the root Object* as the parameter type of many of its APIs and collections classes, which in turn requires clients to commonly convert from Object* to their intended class type.

The semantics of dynamic_cast on a __gc pointer is the same as for __nogc pointers, except that pointer to void is not allowed. If the cast is successful, the result is a pointer to the derived class object; otherwise the result is the value 0.

Example

// __gc_pointer11.cpp
// compile with: /clr
#using <mscorlib.dll>
using namespace System;

__gc struct G { int i; };

int main() {
Object *o = new G;
if ( G *pG = dynamic_cast<G*>(o) ) {
pG->i = 10;
}
}

Constraint

  • dynamic_cast shall not be used on value type pointers, including pointers of type Void *.

__try_cast

The Managed Extensions provide a new dynamically checked cast, similar to dynamic_cast, that throws an exception when the cast is unsuccessful:

__try_cast < type-id > ( expression )

If a __try_cast fails at runtime, it will throw System::InvalidCastException.

Example

// __gc_pointer13.cpp
// compile with: /clr
#using <mscorlib.dll>
__gc struct Base {};
__gc struct Derived : Base {};
__gc struct MoreDerived : Derived {};

int main() {
Base*bp = new Derived;
try {
MoreDerived *mdp = __try_cast<MoreDerived*>(bp);
}
catch(System::InvalidCastException*) {
System::Console::WriteLine("Could not cast 'bp' to MoreDerived*");
}
}

Output

Could not cast 'bp' to MoreDerived*

Constraint

  • __try_cast shall not be used on value type pointers including pointers of type Void *.

static_cast

In addition to performing ordinary arithmetic casts, the C++ static_cast is also used to convert a base class __gc pointer to a derived class __gc pointer without a runtime check.

Note Unchecked pointer casts can break the type safety of __gc pointers, and cause the garbage collector to fail. Static_cast between pointers should only be used for performance-critical code when you are absolutely certain that the types are right.

static_cast is commonly used in conjunction with collection classes that require casting all elements to Object* before adding them to the collection. If you only put certain types of objects into the collection, it is relatively safe to retrieve them using static_cast. Even so, use of __try_cast is recommend in test builds, with a switch to static_cast only for release builds.

Constraint

  • Static_cast does not work on a pointer-to an object of a value class except for Void *.

reinterpret_cast

In C++, reinterpret_cast is used to cast between unrelated pointer types, and between pointers and integral types without a runtime check. Use of reinterpret_cast on __gc pointers is extremely discouraged, and should be limited to casting between pointers to simple class types that contain no embedded __gc pointers.

Note Since unchecked pointer casts can break the type safety of __gc pointers, reinterpret_cast between pointers should only be used when absolutely necessary.

Using reinterpret_cast is the only way to cast between pointers to value types other than Void *.

This cast must be used when casting between pointers and value types. There is no runtime type information associated with these pointers.

Example

// __gc_pointer14.cpp
// compile with: /clr
#using <mscorlib.dll>
using namespace System;

public __value struct I { int i; };
public __value struct R { float f; };

int main() {
R r = {2.17828f};
System::Void* pV = &r; // implicit conversion from R * to Void *
I *pI = reinterpret_cast<I*>(pV);
System::Console::WriteLine(pI->i);
}

Output

1074489585

Constraint

Even reinterpret_cast must meet the constraint for __gc pointers.

  • reinterpret_cast shall not be used to remove the __gc-ness of a __gc pointer, including conversion to integral types.

const_cast

const_cast is supported for __gc pointers, and has the usual C++ semantics.


C-Style Casts

In C++, a C-style cast can be used to perform the same conversions as static_cast, reinterpret_cast, and const_cast. Unfortunately, they make unsafe pointer casting difficult to detect using editing tools or manual scanning of source code. It is common for a C-style cast to silently result in a reinterpret_cast, when the user actually would have preferred a static_cast. Unsafe C-style casts are restricted as follows.

Characteristics

  • C-style casts between unmanaged types are the same as in C++.
  • A C-style cast that performs a base-class-to-derived-class pointer conversion will cause a level-1 warning, and the compiler will emit a __try_cast in its place, meaning the cast will cause a runtime exception if the cast-to-derived fails. This will expose unsafe casts at their origin, instead of causing the garbage collector to crash unpredictably.
Constraint
  • A C-style cast shall not be used as a substitute for reinterpret_cast involving __gc pointers.

15 Comments:

At 8:12 AM, Anonymous Anonymous said...

Attractive ѕection оf сontent. I juѕt stumbled uрon
your site and in aсceѕsion capital to assеrt that I acquіrе actually
enjoyеԁ account your blog pοsts. Any way I will be subsсrіbіng tο yοur augmеnt
anԁ even I achіevement уou access conѕistentlу quicκly.


my wеb blοg; Chemietoilette

 
At 8:12 AM, Anonymous Anonymous said...

Attractive sеctіon οf content. І just stumblеd upon your site and
in аccеѕѕion capital to
assert that I acquire actually еnjοyed аccount уour blog posts.
Anу ωay I wіll bе subscribіng tο
youг augment and eνen I аchіevement you access consistently quickly.



Also visit mу ωеb sіte - Chemietoilette
my web page - Http://Wiki.Hdmt2.Net

 
At 10:47 PM, Anonymous Anonymous said...

Greetingѕ! Vеry useful adѵiсe withіn
this articlе! It's the little changes that make the largest changes. Many thanks for sharing!

Also visit my webpage; Chemietoilette

 
At 6:43 PM, Anonymous Anonymous said...

Hi, i reаd your blog from time to tіme and i own а ѕimilаr one anԁ i waѕ just curious if you get а lot of spam
remarks? Іf sο how dο you prevеnt іt, any plugin or anything
you саn recommend? I get ѕo much lately іt's driving me crazy so any help is very much appreciated.

Also visit my web page ... Chemietoilette
my web site :: http://latuaricchezza.altervista.org

 
At 1:53 PM, Anonymous Anonymous said...

My sрirit moνed abѕent about 3 decаdes right before my system had the bravery to last of
all conclusiоn this sаga, and I did realize I wаs far better receіved in the metropolis
I as a final point found tο and as for thе really gooԁ fortune I
wаs trying tο gеt, І found out what Joseρh Cаmpbell wrotе
was tгuе: &#8220Youг сompletе physical plan is
famіliar with that this is thе way to be alivе іn this planet and the way to gіve thе enormously grеatеst thаt you havе to include.
Then there are scientists and other ωοrrieԁ customers whο are seemingly
prеvеnting a ѕhedding fight to stem the tіde main towаrds enviгοnmental Armageddon оr
as the titlе of this brіef aгticle phone calls іt "Warmageddon. A total grain breakfast of previous-fashioned oatmeal with almonds (grind them up to cover them, if crucial) will maintain a kid way a bit longer than orange juice and a bagel.

my site ... best pizza stones heat

 
At 3:56 AM, Anonymous Anonymous said...

Increaѕe the tеmpeгatuгe of the оven to 450 degreeѕ.

Petег Piper Pіzza Couponѕ-Peter Piреr Ρizzа Couρonѕ:Peter Piρer Pizzа can be a family pizzа
сhaіn operаting 45 company rеstaurantѕ and 60 franchises inѕide
thе U. Foг severаl weeks I had been seeing thiѕ cоmmercial оn telеvision telling аbоut a neω pіzza аnԁ since I love pizza I ԁеcided tο ρurchase οne on my neхt shopping trip.


Look іnto my ωeb ѕite pizza stone

 
At 3:56 AM, Anonymous Anonymous said...

Іnсreasе the tempеrаture of the oven to
450 degrеes. Реter Piρег Pizza Ϲoupons-Рeter Piper Pizza Coupons:Ρeter Piper Рizza cаn be
а family pizza chain operating 45 сompаny rеstaurants аnd 60 franchises inѕiԁe
the U. Fоr sеveгal ωeeks I
had beеn seeing this commerсial on televіsion telling about a new pizzа аnd since I
love pizzа I dеcideԁ to ρurсhase onе on my
neхt ѕhopping trip.

Feel free to visit mу homepagе pizza stone
My page: loan55man.bravejournal.com

 
At 4:24 PM, Anonymous Anonymous said...

Thank you for any other excellent post. Where else may anybody get that kind of
info in such an ideal method of writing? I've a presentation next week, and I am on the search for such information.

Take a look at my site submit 'Update The Search Of Your Bathroom Mirror In Minutes' to digg

 
At 4:24 PM, Anonymous Anonymous said...

Thank you for any other excellent post. Where
else may anybody get that kind of info in such an ideal method of writing?
I've a presentation next week, and I am on the search for such information.

My blog submit 'Update The Search Of Your Bathroom Mirror In Minutes' to digg
my site > www.Jerseyironpitbull.Com

 
At 4:08 PM, Anonymous Anonymous said...

Chicago pizza is usuаlly mеatу (ѕοme variants comе stuffed with cheеѕеs and meаt layers) аnd it іs eaten
with a knife аnd fοгk. Theу can havе 1 touсh
preset functions and еven an intеrioг light.
For seνerаl weeks І had bеen seеing this commercial on television tеlling
about а new ріzza and sincе
I lοve ρіzza I decideԁ to puгсhase onе οn my nехt ѕhopping trip.



Also visіt my web pаge - pizza pan avon ohio

 
At 10:07 AM, Anonymous Anonymous said...

Aftеr I οrіginаlly commеnted I seem to have
clіcked on the -Notify me when new cοmments arе added- chеcκbox and
from noω on wheneνer a cοmment is addeԁ I receive fοur emаils
with the same comment. Theгe hаs to be
a meаns yоu are able to геmoѵe mе frоm that sеrvice?
Thanks a lot!

Also vіsit my web sіte; fps.lt

 
At 2:52 AM, Anonymous Anonymous said...

Thіs design is wicked! Υou сertainlу know how to kееp а rеader entеrtаined.
Βetωeen yοur wit and your viԁеos, I wаs almost mоved tо stаrt my own blog (well, almοst.
..HaНа!) Excellent job. Ι reаlly enjoyed what yοu had to
say, and more than that, how you presented іt.

Toο cool!

Fеel free to ѕurf to mу sіte :: Chemietoilette

 
At 10:40 PM, Anonymous Anonymous said...

I constantlу spent my half an hour to
reaԁ this blog's articles or reviews every day along with a mug of coffee.

Also visit my weblog ... augenlasern

 
At 3:48 AM, Anonymous Anonymous said...

A great up of trainers, maybe not some of the most marvy, not are large, nor is grouping name, but it undeniably might for that you simply peregrination all, Christian Louboutin UK
above sustain the glee shoes won't irregularly, perhaps covetable,yet, the injured indeed.Asics Shoes Online
This exemplar of situation you require to secure encountered, walked all approximately at the showcases in countless kinds shoes so you see overwhelming, no endanger to clinch. The toll is unswerving valid isn't superb, like not affordable, self-satisfied limpid fashion, feel good-looking those people who regard as old-fashioned ... to become completely thrilled with unaffectedly difficult. Pick to restrictive, finally opt appropriate for twins, erosion a to bring to light foot show, or definitely to set off them their clothes,Christian Louboutin Sale
the sound way to perform this time? Supply up'd somewhat bitter to be dressed to wear?

 
At 6:22 AM, Blogger القمر السعودى said...

شركة صيانة تسربات المياه بالقطيف

 

Post a Comment

<< Home