Warning C5651

キャンセル
次の結果を表示 
表示  限定  | 次の代わりに検索 
もしかして: 
2,058件の閲覧回数
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,130件の閲覧回数
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,130件の閲覧回数
mimais
Contributor I

Thank you very much.

Mirko. 

0 件の賞賛
返信
1,131件の閲覧回数
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 件の賞賛
返信