Prev: Compiling C++ Templates as opposed to Preprocessing them.
Next: where error for this static_assert
From: Sadanand on 31 Jul 2010 01:21 Hi friends, I did find a strange issue while working on a live project, I have a frame work, static library and main application The code simply looks like this //Main Application void MyClass::MyClass() { //Call for getValue , getValue is the function of framework result = DFrameWorkInstance->getValue(&m_DefaultValue); // m_DefaultValue is a member declared as long int in MyClass } //Framework int FrameWork::getValue( long int *dwOutValue) { // This getValue in turn calls getValue of static lib if(dwOutValue) result = staticLibInstance->getValue((float*) dwOutValue); else return 0; printf("Out Value = %ld \n",*dwOutValue); return 1; } //Static lib int Static_lib:: getValue(float *outValue) { float tempValue = 44100; if(outValue) { *outValue = tempValue; printf("Out Value = %ld \n",*outValue ; } else return 0; return 1; } Now what exactly happening ? when I print the value of out parameter in static lib , it give proper value when I print the value in frame work after getValue call , it will print some junk big value What I did suspect after typecasting from long int to float the value being changed ( strange behavior it suppose to work, but not working ) Then I did change the framework code like this //Framework int FrameWork::getValue( long int *dwOutValue) { float tempValue; // This getValue in turn calls getValue of static lib if(dwOutValue) { result = staticLibInstance->getValue(&tempValue); *dwOutValue = tempValue; } else return 0; printf("Out Value = %ld \n",*dwOutValue); return 1; } Now it works fine. Finally I didn't get what was wrong? typecasting from long int to float suppose to work fine, but why it didn't work? infact it has to work since both unsigned long and float are of 4 bytes (32 bits ). I am using GCC4.0 , and Mac platform Thanks & Regards, Sadanand. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Blazej on 31 Jul 2010 23:33 > Now it works fine. Finally I didn't get what was wrong? typecasting > from long int to float suppose to work fine, but why it didn't work? > infact it has to work since both unsigned long and float are of 4 > bytes (32 bits ). > I am using GCC4.0 , and Mac platform The main issue here is that you downcast from float to long. You just change the way the bits are interpreted, nothing more. The behavior is platform dependent. Regards, Blazej -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Nick Hounsome on 31 Jul 2010 23:33 On 31 July, 17:21, Sadanand <steggi...(a)gmail.com> wrote: Suppose that the int representation of an int n is 0x1234 and the float representation is 0xabcd (you should not expect them to be the same even for the same number) Consider the following sequence of C++ and address/value memory layout int n = 0x1234; //0x0000: 0x1234 float f = 42; //0x0002: 0xabcd int *np = &n; //0x0004: 0x0000 float *fp = &f; //0x0006: 0x0002 int* np2 = (int*)fp; // Note that the compiler will not remember how it got np2. //0x0008: 0x0002; !!!! A pointer is a pointer there is no value conversion to be done int n2 = *np; // Copy the two bytes (sizeof int) pointed to by np to &n2 //0x0010: 0x1234 int n3 = *np2; // Copy the two bytes pointed to by np2 to &n3 OOPS! //0x0012: 0xabcd compare with: int n3 = (int)f; // read the float f,convert it to int and store it //0x0012: 0x1234 If you stick to new style casts you will find that you can use a static_cast for value conversion but a reinterpret_cast is needed for the pointer conversion: int n3 = static_cast<int>(f); // please do the right thing int * np2 = reinterpret_cast<int*>(fp); // trust me - you might think that fp points to a float but it doesn't There are a very few circumstances when a reinterpret_cast is useful - basically serialization and generic pointer holding - so if you need to reinterpret_cast to anything other than <unsigned char*> or <void*> you have almost certainly done something wrong so, if possible, always enable compiler warnings for old style casts and don't use them. The compiler will then help you to avoid this sort of bug. -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: Mathias Gaunard on 31 Jul 2010 23:31 On Jul 31, 5:21 pm, Sadanand <steggi...(a)gmail.com> wrote: > int Static_lib:: getValue(float *outValue) > { > float tempValue = 44100; > if(outValue) > { > *outValue = tempValue; > printf("Out Value = %ld \n",*outValue ; That's undefined behaviour. Use printf("Out Value = %f\n", *outValue); -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
From: avs234 on 31 Jul 2010 23:30 On Jul 31, 8:21 pm, Sadanand <steggi...(a)gmail.com> wrote: > Hi friends, > I did find a strange issue while working on a live project, > I have a frame work, static library and main application > The code simply looks like this > //Main Application > void MyClass::MyClass() > { > //Call for getValue , getValue is the function of framework > result = DFrameWorkInstance->getValue(&m_DefaultValue); // > m_DefaultValue is a member declared as long int in MyClass > > } > > //Framework > int FrameWork::getValue( long int *dwOutValue) > { > // This getValue in turn calls getValue of static lib > if(dwOutValue) > result = staticLibInstance->getValue((float*) dwOutValue); > else > return 0; > printf("Out Value = %ld \n",*dwOutValue); > > return 1; > > } > > //Static lib > int Static_lib:: getValue(float *outValue) > { > float tempValue = 44100; > if(outValue) > { > *outValue = tempValue; > printf("Out Value = %ld \n",*outValue ; > } > else > return 0; > return 1; > > } > > Now what exactly happening ? > when I print the value of out parameter in static lib , it give > proper value > when I print the value in frame work after getValue call , it will > print some junk big value > What I did suspect after typecasting from long int to float the value > being changed ( strange behavior it suppose to work, but not working ) > Then I did change the framework code like this > //Framework > int FrameWork::getValue( long int *dwOutValue) > { > float tempValue; > // This getValue in turn calls getValue of static lib > if(dwOutValue) > { > result = staticLibInstance->getValue(&tempValue); > *dwOutValue = tempValue;} > > else > return 0; > printf("Out Value = %ld \n",*dwOutValue); > > return 1; > > } > > Now it works fine. Finally I didn't get what was wrong? typecasting > from long int to float suppose to work fine, but why it didn't work? > infact it has to work since both unsigned long and float are of 4 > bytes (32 bits ). > I am using GCC4.0 , and Mac platform > > Thanks & Regards, > Sadanand. > The 2nd version is ok: you're asking the compiler to convert from float to long, which it does. In the 1st version you're trying to fool the compiler providing the address an object of different type, and the compiler just dumbly copies those 4 bytes to that address without any conversion at all in your StaticLib (which doesn't care that the pointer was initially meant to point to a long). *Never* do pointer typecasting unless you're sure that the objects they are pointed to are somehow alike (e.g., when typecasting from derivative to base class pointers, but not vice versa). -- [ See http://www.gotw.ca/resources/clcm.htm for info about ] [ comp.lang.c++.moderated. First time posters: Do this! ]
|
Pages: 1 Prev: Compiling C++ Templates as opposed to Preprocessing them. Next: where error for this static_assert |