tags:

views:

127

answers:

3

Hi,

While assigning from long to short, LSB 2 bytes is 0, where as MSB is filled with values from the func1() Algorithm values from stack. Why is this happening, why the compiler is trying to get these junk values to the MSB 2bytes?

#include <stdio.h>

unsigned short func1(void); // NB: function prototype !

int main(void)

{

     unsigned long int L = 0;

     unsigned short K = 0;

     L = func1();

      printf("%lu", L); // prints junk values

      K = L; 

      printf("%u", K);  // prints 0

     return 0;
}

unsigned short func1(void)

{

      unsigned short i = 0;

      // Algorithm Logic!!!

      return i; // returns 0
}
A: 

try this:

L = 0x00000000 | func1();

please format code in questions in future

Andrey
@Andrey ORing with 0 doesn't affect the value at all. The compiler should automatically promote the short to long anyway.
Nick Meyer
No, but perhaps it might affect the type? Dunno.
Steven Sudit
sorry, i wrote too few zeros. it will not modify value, but it will expand it and make sure high order bytes are filled with zeroes
Andrey
You don't need to do this. It's the printf statement with the wrong specifier that's causing the problem as you can see from the line "K = L". Need to use %lu as a previous poster mentioned and not %d.
Cthutu
+5  A: 

The specifier for unsigned long is lu. That for unsigned short is hu. You invoke UB by not using the proper specifiers.

dirkgently
Assuming that the range of `unsigned short` fits into `int` on the OP's platform, the `%d` is pefectly fine in the first `printf`, since the `unsigned short` value will be promoted to `int` when passed to `printf`. The second `printf` is incorrect though.
AndreyT
@dirkgently: ??? In C language default argument promotions are *always* applied to variadic arguments, as in this case with `printf`. In fact, default argument promotions are *only* applied for not-declared parameters (variadic or no prototype). That's why they are called *default*. When the parameters are declared, the conversion is not *default*, but rather specific.
AndreyT
Yeah. I had missed 6.5.2.2 para 7.
dirkgently
I'll add to that that conversion from `usigned short` to `int` results in implementation-defined behavior or an implementation-defined signal may be raised.(6.3.1.3 para 3).
dirkgently
@dirkgently: It is not necessarily to `int`. Promotions for `short` (ar any other type smaller tham `int`) are not implementation defined and cannot rise any signals. The range of `unsigned short` always fits into either `int` or `unsigned int` (required by the standard). The compiler is required to choose the proper target type, so no overflow is possible.
AndreyT
The only problem with the first print is that the target type for promotion might be `unsigned int` on some platform, which would require `%u` format speicifrer. Which is why I explicitly noted "assuming range of `unsigned short` fits into `int`".
AndreyT
A: 

There are a number of problems with your code - here is a fixed version which should behave correctly.

#include <stdio.h>

unsigned short func1(void); // NB: function prototype !

int main(void)
{
  unsigned long int L = 0;
  unsigned short K = 0;

  L = func1();
  printf("%lu", L);
  K = L; 
  printf("%u", K);

  return 0;
}

unsigned short func1(void)
{
   unsigned short i = 0;

   // Algorithm Logic!!!

   return i; // returns 0
}
Paul R
Hi Paul,Even with the changes it did not work. I am seeing MSB filled with junk values and LSB with 0. Is it a compiler issue?
Pradna
How are you seeing that ? what output does the exact above program produce on your system - and what compiler are you using ?
nos
@Pradna - the code above compiles without warning with `gcc -Wall` and generates the expected output (0 in both cases). What compiler and OS are you using ?
Paul R