Why does std::array not have an operator T*? - c++

With C arrays, it's been the case that simply naming an array has the same effect as writing &foo[0] for something approaching 50 years.
When converting from C style arrays to std::array<> in a project I'm working on, the vast majority of "error"s that appeared were due to the above property of C arrays.
In all cases, the solution was trivial, just append .data(). However it occurred to me that a carefully crafted operator T* ought to directly solve this issue.
Is there any technical reason this operator could not be created?

C-style arrays are sized constructs. You can get the compile-time size of an array via various means. However, when the array decays into a pointer, you lose that compile-time sizing information. Even if the parameter is an "array" type, it's really still just a pointer with no size info. You can use template programming to preserve the size if the array is passed as a function parameter (template<size_t S> void func(T(&param)[S])), but that's it.
This implicit decaying of an array to a pointer is considered by many C++ programmers to be a design flaw in C-style arrays. Indeed, it would hardly be unreasonable to say that lossy conversions are probably not ones which should be implicit. Given that std::array is an attempt to fix as many of the flaws of C-style arrays as possible, allowing it to implicitly decay into a pointer would be counter-productive.
By contrast, C++20's std::span type provides an implicit conversion from a std::array (and C-style arrays, among others). The reason being that such a conversion preserves the information: pointer as well as size. Indeed, the conversion can even preserve the compile-time nature of that size.
Is there any technical reason this operator could not be created?
"Could not"? No.

data() is introduced to have similar interface across multiple STL containers. For example, std::string and std::vector also provide data() which gives address of actual data buffer. So std::array interface was designed to match that. Operator() that you suggest is quite different way, and doesn't seem to be absolutely appropriate. As above commenters also mentioned, the more appropriate is operator T*(), but still this is not how STL designers preferred to do - they introduced data(). Why? Maybe because it is just more readable.

Is there any good reason this operator doesn't exist?
If you mean why there is no operator T*() to automatically provide the cast, one (of multiple) potential reasons is exactly that -- the idea of automatic casting.
Maybe it would be convenient to have the code using std::array to just compile correctly by utilizing operator T*(), and away you go with a program that has been built with no errors. However there are some implications to this:
1) The call to operator T*() is a potential runtime cost that the programmer may not have desired, but just comes along for the ride. In C++, the goal is to only pay for what is desired, and having casting operators just impose themselves goes against this idea.
2) operator T*() and casting operators in general can potentially hide bugs or
bottlenecks in running code, due to usage that the programmer is not aware of.
In my experience, ask a programmer that has a code base littered with casting operators what functions are actually being called, and more times than not, they are not sure what path their code is taking, or they are just plain wrong (and don't realize it until they partake in a debugging session and see all the twists and turns being done by the seemingly innocent casting operators being invoked).
Thus it is deemed far safer for the programmer to explicitly want to "convert" the data by calling a function such as data(), and not by utilizing a operator T*() they may not have been aware of.

Calling data() is a thing you should avoid. It can be useful to have this power for (as in our case migrating code or optimized code processing the guts) however it goes against the safety net std::array provides.
std::array<int, 2> a{1,2};
auto* ptr = a.data();
std::cout << ptr[2]; // boom
Things taking away a safety net should be explicit.

Related

static_cast vs implicit cast [duplicate]

I am new to C++ style casts and I am worried that using C++ style casts will ruin the performance of my application because I have a real-time-critical deadline in my interrupt-service-routine.
I heard that some casts will even throw exceptions!
I would like to use the C++ style casts because it would make my code more "robust". However, if there is any performance hit then I will probably not use C++ style casts and will instead spend more time testing the code that uses C-style casts.
Has anyone done any rigorous testing/profiling to compare the performance of C++ style casts to C style casts?
What were your results?
What conclusions did you draw?
If the C++ style cast can be conceptualy replaced by a C-style cast there will be no overhead. If it can't, as in the case of dynamic_cast, for which there is no C equivalent, you have to pay the cost one way or another.
As an example, the following code:
int x;
float f = 123.456;
x = (int) f;
x = static_cast<int>(f);
generates identical code for both casts with VC++ - code is:
00401041 fld dword ptr [ebp-8]
00401044 call __ftol (0040110c)
00401049 mov dword ptr [ebp-4],eax
The only C++ cast that can throw is dynamic_cast when casting to a reference. To avoid this, cast to a pointer, which will return 0 if the cast fails.
The only one with any extra cost at runtime is dynamic_cast, which has capabilities that cannot be reproduced directly with a C style cast anyway. So you have no problem.
The easiest way to reassure yourself of this is to instruct your compiler to generate assembler output, and examine the code it generates. For example, in any sanely implemented compiler, reinterpret_cast will disappear altogether, because it just means "go blindly ahead and pretend the data is of this type".
Why would there be a performance hit? They perform exactly the same functionality as C casts. The only difference is that they catch more errors at compile-time, and they're easier to search for in your source code.
static_cast<float>(3) is exactly equivalent to (float)3, and will generate exactly the same code.
Given a float f = 42.0f
reinterpret_cast<int*>(&f) is exactly equivalent to (int*)&f, and will generate exactly the same code.
And so on. The only cast that differs is dynamic_cast, which, yes, can throw an exception. But that is because it does things that the C-style cast cannot do. So don't use dynamic_cast unless you need its functionality.
It is usually safe to assume that compiler writers are intelligent. Given two different expressions that have the same semantics according to the standard, it is usually safe to assume that they will be implemented identically in the compiler.
Oops: The second example should be reinterpret_cast, not dynamic_cast, of course. Fixed it now.
Ok, just to make it absolutely clear, here is what the C++ standard says:
§5.4.5:
The conversions performed by
a const_cast (5.2.11)
a static_cast (5.2.9)
a static_cast followed by a const_cast
a reinterpret_cast (5.2.10), or
a reinterpret_cast followed by a const_cast.
can be performed using the cast
notation of explicit type conversion.
The same semantic restrictions and
behaviors apply. If a conversion can
be interpreted in more than one of the
ways listed above, the interpretation
that appears first in the list is
used, even if a cast resulting from
that interpretation is ill-formed.
So if anything, since the C-style cast is implemented in terms of the C++ casts, C-style casts should be slower. (of course they aren't, because the compiler generates the same code in any case, but it's more plausible than the C++-style casts being slower.)
There are four C++ style casts:
const_cast
static_cast
reinterpret_cast
dynamic_cast
As already mentioned, the first three are compile-time operations. There is no run-time penalty for using them. They are messages to the compiler that data that has been declared one way needs to be accessed a different way. "I said this was an int*, but let me access it as if it were a char* pointing to sizeof(int) chars" or "I said this data was read-only, and now I need to pass it to a function that won't modify it, but doesn't take the parameter as a const reference."
Aside from data corruption by casting to the wrong type and trouncing over data (always a possibility with C-style casts) the most common run-time problem with these casts is data that actually is declared const may not be castable to non-const. Casting something declared const to non-const and then modifying it is undefined. Undefined means you're not even guaranteed to get a crash.
dynamic_cast is a run-time construct and has to have a run-time cost.
The value of these casts is that they specifically say what you're trying to cast from/to, stick out visually, and can be searched for with brain-dead tools. I would recommend using them over using C-style casts.
When using dynamic_cast several checks are made during runtime to prevent you from doing something stupid (more at the GCC mailing list), the cost of one dynamic_cast depends on how many classes are affected, what classes are affected, etc.
If you're really sure the cast is safe, you can still use reinterpret_cast.
Although I agree with the statement "the only one with any extra cost at runtime is dynamic_cast", keep in mind there may be compiler-specific differences.
I've seen a few bugs filed against my current compiler where the code generation or optimization was slightly different depending on whether you use a C-style vs. C++-style static_cast cast.
So if you're worried, check the disassembly on hotspots. Otherwise just avoid dynamic casts when you don't need them. (If you turn off RTTI, you can't use dynamic_cast anyway.)
The canonical truth is the assembly, so try both and see if you get different logic.
If you get the exact same assembly, there is no difference- there can't be. The only place you really need to stick with the old C casts is in pure C routines and libraries, where it makes no sense to introduce C++ dependence just for type casting.
One thing to be aware of is that casts happen all over the place in a decent sized piece of code. In my entire career I've never searched on "all casts" in a piece of logic- you tend to search for casts to a specific TYPE like 'A', and a search on "(A)" is usually just as efficient as something like "static_cast<A>". Use the newer casts for things like type validation and such, not because they make searches you'll never do anyway easier.

Which C++ idioms are deprecated in C++11?

With the new standard, there are new ways of doing things, and many are nicer than the old ways, but the old way is still fine. It's also clear that the new standard doesn't officially deprecate very much, for backward compatibility reasons. So the question that remains is:
What old ways of coding are definitely inferior to C++11 styles, and what can we now do instead?
In answering this, you may skip the obvious things like "use auto variables".
Final Class: C++11 provides the final specifier to prevent class derivation
C++11 lambdas substantially reduce the need for named function object (functor) classes.
Move Constructor: The magical ways in which std::auto_ptr works are no longer needed due to first-class support for rvalue references.
Safe bool: This was mentioned earlier. Explicit operators of C++11 obviate this very common C++03 idiom.
Shrink-to-fit: Many C++11 STL containers provide a shrink_to_fit() member function, which should eliminate the need swapping with a temporary.
Temporary Base Class: Some old C++ libraries use this rather complex idiom. With move semantics it's no longer needed.
Type Safe Enum Enumerations are very safe in C++11.
Prohibiting heap allocation: The = delete syntax is a much more direct way of saying that a particular functionality is explicitly denied. This is applicable to preventing heap allocation (i.e., =delete for member operator new), preventing copies, assignment, etc.
Templated typedef: Alias templates in C++11 reduce the need for simple templated typedefs. However, complex type generators still need meta functions.
Some numerical compile-time computations, such as Fibonacci can be easily replaced using generalized constant expressions
result_of: Uses of class template result_of should be replaced with decltype. I think result_of uses decltype when it is available.
In-class member initializers save typing for default initialization of non-static members with default values.
In new C++11 code NULL should be redefined as nullptr, but see STL's talk to learn why they decided against it.
Expression template fanatics are delighted to have the trailing return type function syntax in C++11. No more 30-line long return types!
I think I'll stop there!
At one point in time it was argued that one should return by const value instead of just by value:
const A foo();
^^^^^
This was mostly harmless in C++98/03, and may have even caught a few bugs that looked like:
foo() = a;
But returning by const is contraindicated in C++11 because it inhibits move semantics:
A a = foo(); // foo will copy into a instead of move into it
So just relax and code:
A foo(); // return by non-const value
As soon as you can abandon 0 and NULL in favor of nullptr, do so!
In non-generic code the use of 0 or NULL is not such a big deal. But as soon as you start passing around null pointer constants in generic code the situation quickly changes. When you pass 0 to a template<class T> func(T) T gets deduced as an int and not as a null pointer constant. And it can not be converted back to a null pointer constant after that. This cascades into a quagmire of problems that simply do not exist if the universe used only nullptr.
C++11 does not deprecate 0 and NULL as null pointer constants. But you should code as if it did.
Safe bool idiom → explicit operator bool().
Private copy constructors (boost::noncopyable) → X(const X&) = delete
Simulating final class with private destructor and virtual inheritance → class X final
One of the things that just make you avoid writing basic algorithms in C++11 is the availability of lambdas in combination with the algorithms provided by the standard library.
I'm using those now and it's incredible how often you just tell what you want to do by using count_if(), for_each() or other algorithms instead of having to write the damn loops again.
Once you're using a C++11 compiler with a complete C++11 standard library, you have no good excuse anymore to not use standard algorithms to build your's. Lambda just kill it.
Why?
In practice (after having used this way of writing algorithms myself) it feels far easier to read something that is built with straightforward words meaning what is done than with some loops that you have to uncrypt to know the meaning. That said, making lambda arguments automatically deduced would help a lot making the syntax more easily comparable to a raw loop.
Basically, reading algorithms made with standard algorithms are far easier as words hiding the implementation details of the loops.
I'm guessing only higher level algorithms have to be thought about now that we have lower level algorithms to build on.
You'll need to implement custom versions of swap less often. In C++03, an efficient non-throwing swap is often necessary to avoid costly and throwing copies, and since std::swap uses two copies, swap often has to be customized. In C++, std::swap uses move, and so the focus shifts on implementing efficient and non-throwing move constructors and move assignment operators. Since for these the default is often just fine, this will be much less work than in C++03.
Generally it's hard to predict which idioms will be used since they are created through experience. We can expect an "Effective C++11" maybe next year, and a "C++11 Coding Standards" only in three years because the necessary experience isn't there yet.
I do not know the name for it, but C++03 code often used the following construct as a replacement for missing move assignment:
std::map<Big, Bigger> createBigMap(); // returns by value
void example ()
{
std::map<Big, Bigger> map;
// ... some code using map
createBigMap().swap(map); // cheap swap
}
This avoided any copying due to copy elision combined with the swap above.
When I noticed that a compiler using the C++11 standard no longer faults the following code:
std::vector<std::vector<int>> a;
for supposedly containing operator>>, I began to dance. In the earlier versions one would have to do
std::vector<std::vector<int> > a;
To make matters worse, if you ever had to debug this, you know how horrendous are the error messages that come out of this.
I, however, do not know if this was "obvious" to you.
Return by value is no longer a problem. With move semantics and/or return value optimization (compiler dependent) coding functions are more natural with no overhead or cost (most of the time).

Few doubts about casting operators in C++

The reinterpret_cast as we know can cast any pointer type to any another pointer type. The question I want to ask regarding this cast operator are:
How does reinterpret_cast work, What is the magic(the internal implementation) that allows reinterpret_cast to work?
How to ensure safety when using reinterpret_cast? As far as i know, it doesn't guarantee of safe casting, So what precaution to take while using reinterpret_cast?
What is the practical usage of this operator. I have not really encountered it in my professional programing experience, wherein I could'nt get around without using this operator.Any practical examples apart from usual int* to char* will be highly helpful and appreciated.
One other Question regarding casting operators in general:
Casting operators(static_cast, dynamic_cast, const_cast, reinterpret_cast) are all called Operators i.e is to the best of my understanding, So is it correct statement to make that casting operators cannot be overloaded unlike most other operators (I am aware not all operators can be overloaded and I am aware of which can't be(except the Q I am asking, Please refrain flaming me on that) Just I had this doubt that since they are operators, what does the standard say about these?
There is no magic. reinterpret_cast normally just means (at least try to) treat what you find at this address as if it was the type I've specified. The standard defines little enough about what it does that it could be different from that, but it rarely (if ever) really is.
In a few cases, you can get safety from something like a discriminated union. For example, if you're reading network packets, and read enough to see that what you've received is a TCP packet, then you can (fairly) safely do a reinterpret_cast from IPHdr to TCPHdr (or whatever names you happen to have used). The compiler won't (again, normally) do much though -- any safety is up to you to implement and enforce.
I've used code like I describe in 2), dealing with different types of network packets.
For your final question: you can overload casting for a class:
class XXX {
public:
operator YYY() { return whatever; }
};
This can be used for conversions in general though -- whether done by a static_cast, C-style cast, or even an implicit conversion. C++0x allows you to add an explicit qualifier so it won't be used for implicit conversions, but there's still no way to differentiate between a static_cast and a C-style cast though.
First, it's unclear what you mean by "non-standard pointer". I think your premise is flawed. Happily it doesn't seem to affect the questions.
"How does [it] work?" Well, the intent, as you can guess from the name, is to just change the interpretation of a bitpattern, perhaps extending or shorting as appropriate. This is a kind of change of type where the bitpattern is left unchanged but the interpretation and hence conceptual value is changed. And it's in contrast to a kind of change of type where the conceptual value is kept (e.g. int converted to double) while the bitpattern is changed as necessary to keep the conceptual value. But most cases of reinterpret_cast have implementation defined effect, so for those cases your compiler can do whatever it wants -- not necessarily keeping the bitpattern -- as long as it is documented.
"How to ensure safety" That is about knowing what your compiler does, and about avoiding reinterpret_cast. :-)
"What is the practical usage". Mostly it is about recovering type information that's been lost in C-oriented code where void* pointers are used to sort of emulate polymorphism.
Cheers & hth.,
reinterpret_cast generally lets you do some very bad things. In the case of casting a pointer it will permit casting from one type to another which has absolutely no reason to assume this should work. It's like saying "trust me I really want to do this". What exactly this does is unpredictable from one system to the next. On your system it might just copy the bit-patterns, where as on another one it could transform them in some (potentially useful) way.
e.g.
class Foo {
int a;
};
class Bar {
int a;
};
int main() {
Foo a;
// No inheritance relationship and not void* so must be reinterpret_cast
// if you really want to do it
Bar *b = reinterpret_cast<Bar*>(&a);
char buffer[sizeof(Bar)];
Bar *c = reinterpret_cast<Bar*>(buffer); // alignment?
}
Will quite happily let you do that, no matter what the scenario. Sometimes if you're doing low-level manipulation of things this might actually be what you want to do. (Imagine char * of a buffer casting to something user defined type)
Potential pitfalls are huge, even in the simplest case like a buffer, where alignment may well be a problem.
With dlsym() on Linux it's useful to be able to cast void* to a function pointer, which is otherwise undefined behaviour in C++. (Some systems might use separate address spaces or different size pointers!). This can only be done with reinterpret_cast in C++.
reinterpret_cast only works on pointers. The way it works is that it leaves the value of the pointer alone and changes the assumed type information about it. It says, "I know these types are not equivalent, but I want you to just pretend this is now a pointer to T2." Of course, this can cause any number of problems if you use the T2 pointer and it does not point to a T2.
There are very few guarantees about reinterpret_cast, which is why it is to be so avoided. You're really only allowed to cast from T1 to T2 and then back to T1 and know that, given some assumptions, that the final result will be the same as what you started with.
The only one I can think of is casting a char* to an unsigned char*. I know that the underlying representation is the same in my implementation so I know the cast is safe. I can't use a static cast though because it's a pointer to a buffer. In reality, you'll find very little legitimate use of reinterpret_cast in the real world.
Yes, they are operators. AFAIK you can't override them.
One "practical" use of reinterpret_cast.
I have a class where the members are not meant to be read. Example below
class ClassWithHiddenVariables
{
private:
int a;
double m;
public:
void SetVariables(int s, int d)
{
a = s;
m = d;
}
};
This class is used in a thousand places in an application without a problem.
Now, because of some reason I want see the members in one specific part. However, I don't want to touch the existing class.So break the rules as follows.
Create another class with the same bit pattern and public visibility. Here the original class contains an int and double.
class ExposeAnotherClass
{
public:
int a_exposed;
double m_exposed;
};
When you want to see members of the ClassWithHiddenVariables object, use reinterpret_cast to cast to ExposeAnotherClass. Example follows
ClassWithHiddenVariables obj;
obj.SetVariables(10, 20.02);
ExposeAnotherClass *ptrExposedClass;
ptrExposedClass = reinterpret_cast<ExposeAnotherClass*>(&obj);
cout<<ptrExposedClass->a_exposed<<"\n"<<ptrExposedClass->m_exposed;
I don't think this situation ever occurs in real world. But this is just an explanation of reinterpret_cast which considers objects as bit patterns.
reinterpret_cast tells the compiler "shut up, it's a variable of type T*" and there's no safety unless it is really a variable of type T*. On most implementations just nothing is done - the same value in the variable is passed to the destination.
Your class can have conversion operators to any type T* and those conversions will either be invokde implicitly under certain conditions or you can invoke them explicitly using static_cast.
I've used reinterpret_cast a lot in Windows programming. Message handling uses WPARAM and LPARAM parameters that need casting to the correct types.
reinterpret_cast is pretty equivalent to a C-style cast. It doesn't guarentee anything; it's there to allow you to do what you need to, in the hopes that you know what you're doing.
If you're looking to ensure safety, use dynamic_cast, as that's what it does. If the cast cannot be completed safely, dynamic_cast returns NULL or nullptr (C++0x).
Casting using the "casting operators" such as static_cast, dynamic_cast, etc.. cannot be overloaded. Straight conversions can, such as:
class Degrees
{
public:
operator double() { ... }
};
The reinterpret_cast as we know can
cast any non-standard pointer to
another non-standard pointer.
Almost, but not exactly. For example, you can't use reinterpret_cast to cast a const int* to an int*. For that, you need const_cast.
How does reinterpret_cast work, What is the magic(the internal
implementation) that allows
reinterpret_cast to work?
There's no magic at all. Ultimately, all data is just bytes. The C++ type system is merely an abstraction layer which tells the compiler how to "interpret" each byte. A reinterpret_cast is similar to a plain C-cast, in that it simply says "to hell with the type system: interpret these bytes as type X instead of type Y!"
How to ensure safety when using reinterpret_cast? As far as i know, it
doesn't guarantee of safe casting, So
what precaution to take while using
reinterpret_cast?
Well, reinterpret_cast is inherently dangerous. You shouldn't use it unless you really know what you're doing. Try to use static_cast instead. The C++ type system will protect you from doing anything too dangerous if you use static_cast.
What is the practical usage of this operator. I have not really
encountered it in my professional
programing experience, wherein I
could'nt get around without using this
operator.Any practical examples apart
from usual int* to char* will be
highly helpful and appreciated.
It has many uses, but usually these uses are somewhat "advanced". For example, if you are creating a memory pool of linked blocks, and storing pointers to free blocks on the blocks themselves, you'll need to reinterpret_cast a block from a T* to a T** to interpret the block as a pointer to the next block, rather than a block itself.

Is C++ explicit conversion really that bad?

My knowledge of C++ at this point is more academic than anything else. In all my reading thus far, the use of explicit conversion with named casts (const_cast, static_cast, reinterpret_cast, dynamic_cast) has come with a big warning label (and it's easy to see why) that implies that explicit conversion is symptomatic of bad design and should only be used as a last resort in desperate circumstances. So, I have to ask:
Is explicit conversion with named casts really just jury rigging code or is there a more graceful and positive application to this feature? Is there a good example of the latter?
There're cases when you just can't go without it. Like this one. The problem there is that you have multiple inheritance and need to convert this pointer to void* while ensuring that the pointer that goes into void* will still point to the right subobject of the current object. Using an explicit cast is the only way to achieve that.
There's an opinion that if you can't go without a cast you have bad design. I can't agree with this completely - different situations are possible, including one mentioned above, but perhaps if you need to use explicit casts too often you really have bad design.
There are situations when you can't really avoid explicit casts. Especially when interacting with C libraries or badly designed C++ libraries (like the COM library sharptooth used as examples).
In general, the use of explicit casts IS a red herring. It does not necessarily means bad code, but it does attract attention to a potential dangerous use.
However you should not throw the 4 casts in the same bag: static_cast and dynamic_cast are frequently used for up-casting (from Base to Derived) or for navigating between related types. Their occurrence in the code is pretty normal (indeed it's difficult to write a Visitor Pattern without either).
On the other hand, the use of const_cast and reinterpret_cast is much more dangerous.
using const_cast to try and modify a read-only object is undefined behavior (thanks to James McNellis for correction)
reinterpret_cast is normally only used to deal with raw memory (allocators)
They have their use, of course, but should not be encountered in normal code. For dealing with external or C APIs they might be necessary though.
At least that's my opinion.
How bad a cast is typically depends on the type of cast. There are legitimate uses for all of these casts, but some smell worse than others.
const_cast is used to cast away constness (since adding it doesn't require a cast). Ideally, that should never be used. It makes it easy to invoke undefined behavior (trying to change an object originally designated const), and in any case breaks the const-correctness of the program. It is sometimes necessary when interfacing with APIs that are not themselves const-correct, which may for example ask for a char * when they're going to treat it as const char *, but since you shouldn't write APIs that way it's a sign that you're using a really old API or somebody screwed up.
reinterpret_cast is always going to be platform-dependent, and is therefore at best questionable in portable code. Moreover, unless you're doing low-level operations on the physical structure of objects, it doesn't preserve meaning. In C and C++, a type is supposed to be meaningful. An int is a number that means something; an int that is basically the concatenation of chars doesn't really mean anything.
dynamic_cast is normally used for downcasting; e.g. from Base * to Derived *, with the proviso that either it works or it returns 0. This subverts OO in much the same way as a switch statement on a type tag does: it moves the code that defines what a class is away from the class definition. This couples the class definitions with other code and increases the potential maintenance load.
static_cast is used for data conversions that are known to be generally correct, such as conversions to and from void *, known safe pointer casts within the class hierarchy, that sort of thing. About the worst you can say for it is that it subverts the type system to some extent. It's likely to be needed when interfacing with C libraries, or the C part of the standard library, as void * is often used in C functions.
In general, well-designed and well-written C++ code will avoid the use cases above, in some cases because the only use of the cast is to do potentially dangerous things, and in other cases because such code tends to avoid the need for such conversions. The C++ type system is generally seen as a good thing to maintain, and casts subvert it.
IMO, like most things, they're tools, with appropriate uses and inappropriate ones. Casting is probably an area where the tools frequently get used inappropriately, for example, to cast between an int and pointer type with a reinterpret_cast (which can break on platforms where the two are different sizes), or to const_cast away constness purely as a hack, and so on.
If you know what they're for and the intended uses, there's absolutely nothing wrong with using them for what they were designed for.
There is an irony to explicit casts. The developer whose poor C++ design skills lead him to write code requiring a lot of casting is the same developer who doesn't use the explicit casting mechanisms appropriately, or at all, and litters his code with C-style casts.
On the other hand, the developer who understands their purpose, when to use them and when not to, and what the alternatives are, is not writing code that requires much casting!
Check out the more fine-grained variations on these casts, such as polymorphic_cast, in the boost conversions library, to give you an idea of just how careful C++ programmers are when it comes to casting.
Casts are a sign that you're trying to put a round peg in a square hole. Sometimes that's part of the job. But if you have some control over both the hole and the peg, it would be better not create this condition, and writing a cast should trigger you to ask yourself if there was something you could have done so this was a little smoother.

Performance hit from C++ style casts?

I am new to C++ style casts and I am worried that using C++ style casts will ruin the performance of my application because I have a real-time-critical deadline in my interrupt-service-routine.
I heard that some casts will even throw exceptions!
I would like to use the C++ style casts because it would make my code more "robust". However, if there is any performance hit then I will probably not use C++ style casts and will instead spend more time testing the code that uses C-style casts.
Has anyone done any rigorous testing/profiling to compare the performance of C++ style casts to C style casts?
What were your results?
What conclusions did you draw?
If the C++ style cast can be conceptualy replaced by a C-style cast there will be no overhead. If it can't, as in the case of dynamic_cast, for which there is no C equivalent, you have to pay the cost one way or another.
As an example, the following code:
int x;
float f = 123.456;
x = (int) f;
x = static_cast<int>(f);
generates identical code for both casts with VC++ - code is:
00401041 fld dword ptr [ebp-8]
00401044 call __ftol (0040110c)
00401049 mov dword ptr [ebp-4],eax
The only C++ cast that can throw is dynamic_cast when casting to a reference. To avoid this, cast to a pointer, which will return 0 if the cast fails.
The only one with any extra cost at runtime is dynamic_cast, which has capabilities that cannot be reproduced directly with a C style cast anyway. So you have no problem.
The easiest way to reassure yourself of this is to instruct your compiler to generate assembler output, and examine the code it generates. For example, in any sanely implemented compiler, reinterpret_cast will disappear altogether, because it just means "go blindly ahead and pretend the data is of this type".
Why would there be a performance hit? They perform exactly the same functionality as C casts. The only difference is that they catch more errors at compile-time, and they're easier to search for in your source code.
static_cast<float>(3) is exactly equivalent to (float)3, and will generate exactly the same code.
Given a float f = 42.0f
reinterpret_cast<int*>(&f) is exactly equivalent to (int*)&f, and will generate exactly the same code.
And so on. The only cast that differs is dynamic_cast, which, yes, can throw an exception. But that is because it does things that the C-style cast cannot do. So don't use dynamic_cast unless you need its functionality.
It is usually safe to assume that compiler writers are intelligent. Given two different expressions that have the same semantics according to the standard, it is usually safe to assume that they will be implemented identically in the compiler.
Oops: The second example should be reinterpret_cast, not dynamic_cast, of course. Fixed it now.
Ok, just to make it absolutely clear, here is what the C++ standard says:
§5.4.5:
The conversions performed by
a const_cast (5.2.11)
a static_cast (5.2.9)
a static_cast followed by a const_cast
a reinterpret_cast (5.2.10), or
a reinterpret_cast followed by a const_cast.
can be performed using the cast
notation of explicit type conversion.
The same semantic restrictions and
behaviors apply. If a conversion can
be interpreted in more than one of the
ways listed above, the interpretation
that appears first in the list is
used, even if a cast resulting from
that interpretation is ill-formed.
So if anything, since the C-style cast is implemented in terms of the C++ casts, C-style casts should be slower. (of course they aren't, because the compiler generates the same code in any case, but it's more plausible than the C++-style casts being slower.)
There are four C++ style casts:
const_cast
static_cast
reinterpret_cast
dynamic_cast
As already mentioned, the first three are compile-time operations. There is no run-time penalty for using them. They are messages to the compiler that data that has been declared one way needs to be accessed a different way. "I said this was an int*, but let me access it as if it were a char* pointing to sizeof(int) chars" or "I said this data was read-only, and now I need to pass it to a function that won't modify it, but doesn't take the parameter as a const reference."
Aside from data corruption by casting to the wrong type and trouncing over data (always a possibility with C-style casts) the most common run-time problem with these casts is data that actually is declared const may not be castable to non-const. Casting something declared const to non-const and then modifying it is undefined. Undefined means you're not even guaranteed to get a crash.
dynamic_cast is a run-time construct and has to have a run-time cost.
The value of these casts is that they specifically say what you're trying to cast from/to, stick out visually, and can be searched for with brain-dead tools. I would recommend using them over using C-style casts.
When using dynamic_cast several checks are made during runtime to prevent you from doing something stupid (more at the GCC mailing list), the cost of one dynamic_cast depends on how many classes are affected, what classes are affected, etc.
If you're really sure the cast is safe, you can still use reinterpret_cast.
Although I agree with the statement "the only one with any extra cost at runtime is dynamic_cast", keep in mind there may be compiler-specific differences.
I've seen a few bugs filed against my current compiler where the code generation or optimization was slightly different depending on whether you use a C-style vs. C++-style static_cast cast.
So if you're worried, check the disassembly on hotspots. Otherwise just avoid dynamic casts when you don't need them. (If you turn off RTTI, you can't use dynamic_cast anyway.)
The canonical truth is the assembly, so try both and see if you get different logic.
If you get the exact same assembly, there is no difference- there can't be. The only place you really need to stick with the old C casts is in pure C routines and libraries, where it makes no sense to introduce C++ dependence just for type casting.
One thing to be aware of is that casts happen all over the place in a decent sized piece of code. In my entire career I've never searched on "all casts" in a piece of logic- you tend to search for casts to a specific TYPE like 'A', and a search on "(A)" is usually just as efficient as something like "static_cast<A>". Use the newer casts for things like type validation and such, not because they make searches you'll never do anyway easier.