Warning C5651

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Warning C5651

Jump to solution
1,586 Views
mimais
Contributor I

Dear All,

 

I am using CodeWarrior v.5.9.0 (build 2404) with an MC9S08QE64 MCU and in my project I get the warning:

 

C5651: Local variable <variable> may be not initialized

 

This is the piece of code written to stimulate the warning:

 

typedef struct{
 char par1 :4;
 char par2 :4;
}typeparam;

char fun(typeparam param);

void main(void) {
 typeparam data;
 char ret;
  EnableInterrupts; 
 data.par1 = 2;
 data.par2 = 1;

 ret = fun(data);
 for(;; ) {
    __RESET_WATCHDOG(); 
  } 
}

char fun(typeparam param){
 if(param.par1 == 1) return 1;
 if(param.par2 == 2) return 2;
 return 3;
}

 

The variable data in main function  seems to be initialized but I get the warning:

 

 C5651: Local variable "data" may be not initialized

 

Could someone explain me why? 

Thanks,

Mirko. 

Labels (1)
Tags (1)
0 Kudos
Reply
1 Solution
658 Views
Lundin
Senior Contributor IV
The reason you get the warning is that you pass by value; for some reason CW treats bitfields different than common structs when they are passed by value.

It is common programming practice to always pass struct types by reference in C, no matter their size. If you pass it by reference, the warning disappears for some reason.

That being said, the char type is not allowed for bitfields by ANSI/ISO C, it is listed as "undefined behavior", meaning it will behave completely randomly. Apart from the standard, further issues with bitfields are that they are completely unspecified regarding bit alignment, byte alignment, how the default "int" is treated, padding bytes, etc etc. Bitfields are therefore completely unreliable even when they follow standard C.

The only serious solution is to use bitwise operators. They will yield -exactly- the same machine code, but they will behave in a deterministic way and will be portable to any C/C++ compiler in the world.

Something like this perhaps:

typedef unsigned char typeparam;

enum /* bit masks */
{
  par1   = 0xF0,
  par2   = 0x0F,
};

enum /* bit values */
{
  par1_1 = 0x10,
  par1_2 = 0x20,
  par2_1 = 0x01,
  par2_2 = 0x02,
};

...

void main()
{
 typeparam data;
 char ret;

 data = par1_2 | par2_1;

 ret = fun(data);
 ...
}

char fun(typeparam param)
{
 if((param & par1) == par1_1)
 {
   return 1;
 }
 ...
}
Message Edited by Lundin on 2009-03-30 04:57 PM

View solution in original post

0 Kudos
Reply
2 Replies
658 Views
mimais
Contributor I

Thank you very much.

Mirko. 

0 Kudos
Reply
659 Views
Lundin
Senior Contributor IV
The reason you get the warning is that you pass by value; for some reason CW treats bitfields different than common structs when they are passed by value.

It is common programming practice to always pass struct types by reference in C, no matter their size. If you pass it by reference, the warning disappears for some reason.

That being said, the char type is not allowed for bitfields by ANSI/ISO C, it is listed as "undefined behavior", meaning it will behave completely randomly. Apart from the standard, further issues with bitfields are that they are completely unspecified regarding bit alignment, byte alignment, how the default "int" is treated, padding bytes, etc etc. Bitfields are therefore completely unreliable even when they follow standard C.

The only serious solution is to use bitwise operators. They will yield -exactly- the same machine code, but they will behave in a deterministic way and will be portable to any C/C++ compiler in the world.

Something like this perhaps:

typedef unsigned char typeparam;

enum /* bit masks */
{
  par1   = 0xF0,
  par2   = 0x0F,
};

enum /* bit values */
{
  par1_1 = 0x10,
  par1_2 = 0x20,
  par2_1 = 0x01,
  par2_2 = 0x02,
};

...

void main()
{
 typeparam data;
 char ret;

 data = par1_2 | par2_1;

 ret = fun(data);
 ...
}

char fun(typeparam param)
{
 if((param & par1) == par1_1)
 {
   return 1;
 }
 ...
}
Message Edited by Lundin on 2009-03-30 04:57 PM
0 Kudos
Reply