From: Sadanand on
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
> 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
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
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
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! ]