|
thanx mate,
Im looking for the same kinda functionality too.
Want to make an app similar to yours to manage my network shares.
|
|
|
|
|
Hi All,
I am an intermediate C++ programmer and have a question on the casting operators in C++ when converting between integral data types. My question is as follows:-
If I have a code like this
char c;
int i = 65;
c = i;
VC++ 2005 Complier gives a warning as "possible loss of data. conversion from int to char. So to remove the warning I have the following choices
1. Disable the warning by using #pragma warning (XXXXX:disable). I do not want to use this.
2. Use C style cast to remove the warning as
c = (char)i;
Again I do not want to use this option
3. Use C++ casting operators. I can use either reinterpret_cast as
c = reinterpret_cast<char&>(i);
or static_cast as
c = static_cast<char>(i);
However I am confused between the correct usage. Both these casting operators removes the warning and also gives the desired result.
Can someone please clarify which is the correct usage and if that usage has any side effects?
Thanks and Regards
|
|
|
|
|
The C style cast is fine in this case. If you want to use C++ style casts then use static_cast , because they are similar types. The ‘ reinterpret_cast if for converting between unrelated types, such as an ‘unsigned long’ to a pointer.
INTP
"Program testing can be used to show the presence of bugs, but never to show their absence."Edsger Dijkstra
|
|
|
|
|
psychedelic_fur wrote: 2. Use C style cast to remove the warning as
c = (char)i;
Again I do not want to use this option
Just out of curiosity, why is this option undesired in your situation? From the little I've seen in Java and C#, it appears this is the common form. You understand what it will do in most contexts (especially this one) and it's easier to type and read. You can search for, and find them just as easy in code.
I've never bought the arguments for why the C++ style is superior as no text or article has ever offered a solid affirmative that was not easily rebutted. The examples offered always seem a bit contrived and not so commonplace. I've used this style since the early 90's and it works just fine.
I'm sure someone will pounce on my post with some obscure way to misuse or abuse it but that would be expected as most of the C++ purists are a bit fanatic.
|
|
|
|
|
I do not know about C++ purist, but us old C programmers where definitely known for that. In both C and C++ the C style cast works fine most of the time, and in this case there is no reason not to use it.
I am still not sure why static_cast and reinterpret_cast even exist. On the other hand dynamic_cast is a must for safety, even if we did not have something similar in C.
INTP
"Program testing can be used to show the presence of bugs, but never to show their absence."Edsger Dijkstra
|
|
|
|
|
John R. Shaw wrote: On the other hand dynamic_cast is a must for safety, even if we did not have something similar in C.
I don't think I've ever compiled with the RTTI enabled but I'm the kind of person who uses objects more to group my code logically than for complicated inheritance. I've always stayed at the shallow end of the OOP pool.
|
|
|
|
|
John R. Shaw wrote: dynamic_cast is a must for safety
So is static_cast . You use it when you want the efficiency of a C-style cast but with more type safety. static_cast can not cast between unrelated types. See here[^] for an example.
Steve
|
|
|
|
|
I have never considered using static_cast on derived classes (types), only on integral data types. I also would not use a C-style cast on derived type (it’s just wrong), because I prefer to have the extra safety of C++ casting when it is necessary for such casting. When converting from int to char , or vise versa, I use C-style casts normally. I rarely need to do any casting and when I do I make sure it is done correctly.
P.S. I have read all the posts to date.
INTP
"Program testing can be used to show the presence of bugs, but never to show their absence."Edsger Dijkstra
|
|
|
|
|
I know that the old C style cast works well in this case however I just wanted to find out what is the correct C++ equivalent. It is just out of curiosity. Conside another example
BOOL isCorrect = TRUE;
bool bvalue = (bool)(isCorrect); --- Gives warning C4800
In this case the complier still gives me warnig at Level 4 and the static_cast also doesn't remove the warning (though both of them works and gives the correct result)
bool bvalue = static_cast<bool>(isCorrect); --- Gives warning C4800
the only thing I can do here to remove the warning and get the correct result is use reinterpret_cast as
bool bvalue = reinterpret_cast<bool>(isCorrect) --- error, doesn't compile
bool bvalue = reinterpret_cast<bool&>(isCorrect); or equivalent pointer variation
bool bvalue = *reinterpret_cast<bool*>(&isCorrect);
This works since both "bool" and "BOOL" are basically different types.
I was a bit surprised to find that even old C style cast did not remove the warning, since C style cast is supposed to convert anything into anything.
Thanks
|
|
|
|
|
Fair enough.
I'm not going to claim to know why but I'll take a guess at it.
In VC++ 4.2 on up (likely compiler specific),
BOOL will always maintain it's integral value while bool only allows 2 values for it's type. For instance...
BOOL BOOLVal=5;
TRACE("BOOLVal(5) = %d\n",BOOLVal); // 0 = FALSE. All other values = TRUE
// outputs 5
bool boolVal=(bool)-42;
TRACE("boolVal(-42) = %d\n",boolVal); // Always 0 or 1 (false or true)
// outputs 1
A cast (as we've come to expect it) from BOOL to bool in this case should still truncate the integral value and maintain the bits for the first 8 bits but since bool only allows true and false as 1 and 0, an additional conversion, besides the cast must take place. I'm guessing that's where this operation is no longer a cast and becomes a translation of the value.
// Assembly for a BOOL=bool
119: BOOL isCorrect = 56;
00401973 mov dword ptr [ebp-1Ch],38h
120: bool bvalue = isCorrect;
0040197A xor edx,edx
0040197C cmp dword ptr [ebp-1Ch],0
00401980 setne dl
00401983 mov byte ptr [ebp-20h],dl
// Assembly for a BOOL=BOOL
119: BOOL isCorrect = 56;
00401973 mov dword ptr [ebp-1Ch],38h
120: BOOL bvalue = isCorrect;
0040197A mov edx,dword ptr [ebp-1Ch]
0040197D mov dword ptr [ebp-20h],edx
/*
The setne instruction is "Set byte if not equal (ZF=0)" and it's description says "Sets the destination operand to 0 or 1 depending on the settings of the status flags
(CF, SF, OF, ZF, and PF) in the EFLAGS register"
*/
This is where I'm guessing the translation occurs versus a true cast and probably explains why the compiler takes the liberty to provide warnings. Also, it appears that there is a little history to bool in VC++ changing around version 4.2 and I would guess the warning is to give programmers with code written prior to the version 4.2 change an extra heads up to a potential "breaking change".
Not sure if I got that right but it seems reasonable.
|
|
|
|
|
reinterpret_cast is a compile-time cast between a pointer type and a non-pointer type, or between unrelated pointer types. static_cast is used for all other compile-type typecasts (but it's your responsibility to make sure the cast makes sense).
I always use the C-style casts because they're easier to type, cause less noise in the code, and work just as well as the C++ ones.
|
|
|
|
|
I never use C-style casts except in low level code (such as code that grovels around in a PE file, for example). The code “noise” you refer is a feature and something which, in my opinion, should be embraced rather than shunned. Casts should be both explicit (you cast for many different reasons but they all look the same with C-style casts) and visible (it’s easy to “grep” for C++ style casts and they stick out). The C++ style casts are also safer, for example:
#include "stdafx.h"
#include <iostream>
using namespace std;
class NoClassesDeriveFromMe
{
public:
void Who()
{
cout << "NoClassesDeriveFromMe" << endl;
}
};
class BaseClass
{
public:
void Who()
{
cout << "BaseClass" << endl;
}
};
class DerivedClass : public BaseClass
{
public:
void Who()
{
cout << "DerivedClass" << endl;
}
};
int main(int arvc, char* argv[])
{
NoClassesDeriveFromMe d;
((DerivedClass&)d).Who();
static_cast<DerivedClass&>(d).Who();
return 0;
}
Steve
|
|
|
|
|
#include "stdafx.h"
#include <iostream>
using namespace std;
class BaseClass
{
public:
int m_nValue;
BaseClass() : m_nValue(2)
{
}
void Who()
{
cout << "BaseClass " << m_nValue << endl;
}
};
class DerivedClass : public BaseClass
{
public:
int m_nValue;
DerivedClass() : m_nValue(3)
{
}
void Who()
{
cout << "DerivedClass " << m_nValue << endl;
}
};
int main(int arvc, char* argv[])
{
BaseClass b;
static_cast<DerivedClass&>(b).Who();
// An error but will compile.
// Not as safe as you'd like it to be.
return 0;
}
|
|
|
|
|
It's as safe is it can reasonably be without runtime overhead. There is a relationship between the two classes (some BaseClass es are DerivedClass es) so the cast will succeed; if there is no relationship (no BaseClass es are DerivedClass es) then it fails. In the general case there is no way a compiler can be expected to detect if a particular base class instance is related to a particular derived class (they simple aren't smart enough and separate compilation complicates this even further). If you want complete safety you’ll have to pay a price at runtime and use dynamic_cast .
No one's suggesting that using static_cast will solve all your problems, just that it’s safer than a C-style cast.
Your point is taken however.
Steve
|
|
|
|
|
Here’s a more subtle variation on the same theme as the previous post. Pay particular attention to the "Actions.cpp" file and the comments inside it. I have seen this in real life. Although it seems contrived in a small demo program like this, in the real word it’s not esoteric at all. Real programmers do indeed try to speed up compile times by removing a header and seeing if the program still compiles: in this program, if C-style casts are used, removing a header results in a program that still compiles but behaves incorrectly at runtime. C-style casts, "just say no".
=============================================================
CastProblems.cpp
=============================================================
// CastProblems.cpp : Defines the entry point for the console application.
//
#include "stdafx.h"
#include "Classes.h"
#include "Actions.h"
int main(int argc, char* argv[])
{
Derived d;
GetBase2(&d)->Who();
return 0;
}
=============================================================
Actions.cpp
=============================================================
// Actions.cpp
//
#include "StdAfx.h"
#include "Actions.h"
#include "Classes.h"
// If C-style cast is used below:
// - If this header is included the output is "Base2" (correct).
// - If this header is not included the program compiles but the output is "Base1" (incorrect)!!!
// If a 'static_cast' is used below:
// - If this header is included the output is "Base2" (correct).
// - If this header is not included the program doesn't compile.
const Base2* GetBase2(const Derived *pDerived)
{
// return (const Base2*)pDerived;
return static_cast<const Base2*>(pDerived);
}
=============================================================
Actions.h
=============================================================
// Actions.h
//
#ifndef __ACTIONS_H__
#define __ACTIONS_H__
class Base1;
class Base2;
class Derived;
const Base2* GetBase2(const Derived *pDerived);
#endif // !__ACTIONS_H__
=============================================================
Classes.h
=============================================================
// Classes.h
//
#ifndef __CLASSES_H__
#define __CLASSES_H__
#include <iostream>
class RootBase
{
public:
void Who() const
{
using namespace std;
cout << "Base" << m_Num << endl;
}
protected:
RootBase(int num) : m_Num(num) {}
int m_Num;
};
class Base1 : public RootBase
{
public:
Base1() : RootBase(1) {}
};
class Base2 : public RootBase
{
public:
Base2() : RootBase(2) {}
};
class Derived : public Base1, public Base2
{
public:
};
#endif // !__CLASSES_H__
Steve
|
|
|
|
|
Use static_cast ; reinterpret_cast is the wrong choice in this context.
Steve
|
|
|
|
|
I'm having the following problem.
When I try to run the release version of a VC project, instead of running the program it opens up another instance of visual studio. And that's it. Doesn't run the program.
Debug works fine.
I'm not sure how this occured, but I must have accidentally done something in the project options? or configuration?
Any thoughts on what would cause this? Or how to fix it?
Thanks.
|
|
|
|
|
Create another project, see if the same thing happens. If it does, it's VS. If it doesn't, it's the project.
|
|
|
|
|
I checked out your suggestion, and it works as it should for another project.
Still not sure what the setting or problem could be though. Not sure how to word my google searches to find more info and I haven't seen anything in the project setting that sheds any light on it.
One strange thing is that this is a team project, and my coworkers are not experiencing the same issue, even though we have synced project files.
|
|
|
|
|
CodeGoose wrote: instead of running the program it opens up another instance of visual studio. And that's it. Doesn't run the program.
This means, program is crashing in release version. And there could be various resons for that.
There is an article on site ,"surviving release version". Refer it, to deal the problem.
Prasad
MS MVP - VC++
|
|
|
|
|
What happens when you run the release application from Windows Explorer?
Software Zen: delete this;
|
|
|
|
|
Hello,
sorry for my bad english, is polymorphic function called overloaded? are these terms the same?
and let's say we have code like this:
class A{
int a;
};
class B:public A{
int b;
};
class C:public B{
int c;
};
i am beginner in c++. i want to write an example of polymorphic function in this classes inherit case. Could you advice how should it look like? what is the main point of polymorphic function in classes inherit?
-- modified at 14:32 Saturday 12th May, 2007
Dj_Lord
|
|
|
|
|
i think polymerphic having many form
lets example of function overloading
fun() is a function which can have diffrent signature
fun(int );
fun(int , int );
fun(float);
signature means only no of argument and type of argument not return type;
here name mangling comes to feature which is a good feature in c++;
class a{
public:
a(){
}
a(int var){
}
a(a obj){
}
};
a is a constructor which take diffrent no of arg which is an good example of function overloading.
but constructor can't be inherited
if class a has a function name fun() and another class b derived from base a and derived also has fun() function there is ambigity occur so there is problem which can be overcome by virtual function which is a pure object oriented and from which object oriented start in c++.
biswajit nayak
|
|
|
|
|
Basically you are dealing with inheritance and you need the base class to call a member function in a derived class. What that means: if you convert a pointer to a derived class to that of the base class and call a virtual function that is defined in both classes, the one in the derived class will be called.
class A { virtual const void printName() { cout << "class A" << endl; }
class B: public A { virtual void char printName() { cout << "class B" << endl; }
class C: public B { virtual void char printName() { cout << "class C" << endl; }
C c;
A* pa = dynamic_cast<A*>&c;
pa->printName();
INTP
"Program testing can be used to show the presence of bugs, but never to show their absence."Edsger Dijkstra
|
|
|
|
|
<emp>
<name>white</name>
<adress>amsterdam</adress>
<company>avaya tenovis</company>
</emp>
coding in vc++ but looks like above
biswajit nayak
trainee engineer
|
|
|
|