为什么我得到“C4800:'int':用所有bool值强制值bool?

时间:2016-04-08 18:00:11

标签: visual-studio-2015 c++-cli compiler-warnings

我收到此C4800警告,它指向一行没有与之关联的int值的代码:

CO.Value = (GE_DUAL.Value & GE_SINGLE.Value) | (!GE_DUAL.Value & !IN_TMR.Value);

每个.Value属性的类型为bool

我正在使用VS2015,C ++ / CLI,并且在我的代码中没有找到win32类型BOOL的引用,尽管我已经派生了我自己的类型BOOL,其中每个属性都被强制转换。

我在这个项目中有超过200个其他.cpp个文件,其中包含数千行相似的代码,但我只收到这条确切行的警告。

这更像是一种好奇而不是关注,我可以通过使用逻辑运算符轻松摆脱错误 (见下文) ,但如果有人有我希望听到他们的任何想法。 我在发布之前确实搜索过这个错误,但从来没有得到满意的答案(大多数人都使用int类型并且出现问题。)

CO.Value = (GE_DUAL.Value && GE_SINGLE.Value) || (!GE_DUAL.Value && !IN_TMR.Value);

三行我有这一行:

DUAL.Value = GE_DUAL.Value & !IN_TMR.Value;

哪个没有警告...... 这是一个更完整的代码列表:

public ref class BOOL : IPS::Properties::Bool
{
public:
  BOOL() : Bool() {}
  BOOL(bool val) : Bool() { Value = val;}
  operator bool() { return (bool)ValueAsObject;}
  BOOL(BOOL% b) { m_Value = b.m_Value;}
};

...

  BOOL^             m_IN_TMR;
  BOOL^             m_GE_DUAL;
  BOOL^             m_GE_SINGLE;
  BOOL^             m_CO;

...

  virtual property BOOL%  IN_TMR
  {
    BOOL% get();
    void set(BOOL% val);
  }
  virtual property BOOL%  GE_DUAL
  {
    BOOL% get();
    void set(BOOL% val);
  }
  virtual property BOOL%  GE_SINGLE
  {
    BOOL% get();
    void set(BOOL% val);
  }      
  virtual property BOOL%  CO
  {
    BOOL% get();
    void set(BOOL% val);
  }

...

void _TR_VOTE_MODE::IN_TMR::set(BOOL% val)
{
  m_IN_TMR = %val;
}  
BOOL% _TR_VOTE_MODE::GE_DUAL::get()
{
  return *m_GE_DUAL;
}
void _TR_VOTE_MODE::GE_DUAL::set(BOOL% val)
{
  m_GE_DUAL = %val;
}  
BOOL% _TR_VOTE_MODE::GE_SINGLE::get()
{
  return *m_GE_SINGLE;
}
void _TR_VOTE_MODE::GE_SINGLE::set(BOOL% val)
{
  m_GE_SINGLE = %val;
}  
BOOL% _TR_VOTE_MODE::CO::get()
{
  return *m_CO;
}

...

CO.Value = CI.Value;
if ( CI.Value )
{
  CO.Value = (GE_DUAL.Value & GE_SINGLE.Value) | (!GE_DUAL.Value & !IN_TMR.Value); // Warning C4800??
  if ( CO.Value )
  {
    TMR.Value = IN_TMR.Value;
    DUAL.Value = GE_DUAL.Value & !IN_TMR.Value;
    SINGL.Value = GE_SINGLE.Value & !GE_DUAL.Value;
    ZERO.Value = ! GE_SINGLE.Value;
  }
  else
  {
    U.Value = ReportBadParam(0);
    TMR.Value = false;
    DUAL.Value = false;
    SINGL.Value = false;
    ZERO.Value = false;
  }
}

更新 我做了一些测试,发现,尽管看起来不太可能,这行代码甚至在我的许多其他10万行代码中也是独一无二的。这只是一个仅使用算术运算符的问题。我认为类似的所有其他行都有一些逻辑运算符(与算术混合)

似乎是这一部分:

(GE_DUAL.Value & GE_SINGLE.Value) ===> int

因为那是算术,而另一部分是合乎逻辑的:

(!GE_DUAL.Value & !IN_TMR.Value) ===> bool

因此整行被隐式地转换为int:

(GE_DUAL.Value & GE_SINGLE.Value) | (!GE_DUAL.Value & !IN_TMR.Value)

{bool} != {{int} | {bool}};
 {int} == {{int} | {bool}};

1 个答案:

答案 0 :(得分:1)

  

我收到此C4800警告,它指向一行没有与之关联的int值的代码

按位运算为arithmetic operators,由于integral promotion,布尔操作数被隐式转换为int。类型为int的操作数的算术运算符的结果也是int

至于为什么MS编译器在一种情况下生成此类警告而在其他情况下不生成此警告,我只能猜测它只能在某些情况下预测值。