Warning C5651

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

Warning C5651

跳至解决方案
2,065 次查看
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. 

标签 (1)
标记 (1)
0 项奖励
回复
1 解答
1,137 次查看
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 项奖励
回复
2 回复数
1,137 次查看
mimais
Contributor I

Thank you very much.

Mirko. 

0 项奖励
回复
1,138 次查看
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 项奖励
回复