进行比较时,为什么我必须强制转换为无符号以避免警告
When doing a compare, why must I cast an unsigned to avoid warnings
在下面的示例中,如果我不将 4 转换为无符号,我会收到有关 default.hpp(144) 中的“<=”signed/unsigned 不匹配的警告,然后是更多我不知道的警告跟随。
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <string>
namespace qi = boost::spirit::qi;
typedef std::wstring::const_iterator it_type;
int main()
{
using qi::_1;
using boost::spirit::_pass;
std::wstring testChar(L"450");
auto f = testChar.begin(), l = testChar.end();
unsigned pVal[2] = {0, 0};
qi::uint_parser<unsigned, 10, 1, 1> uint1_p;
bool retVal = qi::parse(f, l, uint1_p[_pass = _1 <= (unsigned)4] >> qi::uint_, pVal[0], pVal[1]);
return 0;
}
在这种情况下是否最好始终投射?
在 Visual Studio 2015 年的基础上使用 Boost 1.61.0
您正在将 uint1_p
解析器的属性与 4
进行比较。 uint1_p{}
的属性类型是 unsigned
,因此您将 unsigned
与 decltype(4)
进行比较,即 int
.
进行混合符号比较是危险的,编译器会对此发出警告。问题是无符号整数算法是 "contagious",这意味着 4
将被提升为无符号整数,而不是相反。如果你有,这是一个风险。 _1 >= 0
因为它永远不会是假的。
令人印象深刻"error novel"是因为警告出现在语义动作评估的Spirit代码深处。如果你写一些更简单的东西,你会得到同样的信息,比如:
#include <iostream>
int main() {
for (unsigned i = 10; i >= 0; --i)
std::cout << i << " ";
}
此程序在 10 次迭代后不会停止。编译器(在本例中为 GCC)警告:
prog.cc:3:29: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
for (unsigned i = 10; i >= 0; --i)
~~^~~~
Q. SHOULD I ALWAYS CAST?
是的。和不。您应该永远不要 使用您编写的 C 风格转换¹。你可以考虑static_cast<unsigned>(4)
。但我会简单地写 4u
:
bool retVal = qi::parse(f, l, uint1_p[_pass = (_1 <= 4u)] >> qi::uint_, pVal[0], pVal[1]);
¹ 请参阅示例
- https://www.securecoding.cert.org/confluence/display/cplusplus/EXP05-CPP.+Do+not+use+C-style+casts
- What is the difference between static_cast<> and C style casting?
在下面的示例中,如果我不将 4 转换为无符号,我会收到有关 default.hpp(144) 中的“<=”signed/unsigned 不匹配的警告,然后是更多我不知道的警告跟随。
#include <boost/spirit/include/qi.hpp>
#include <boost/spirit/include/phoenix_operator.hpp>
#include <string>
namespace qi = boost::spirit::qi;
typedef std::wstring::const_iterator it_type;
int main()
{
using qi::_1;
using boost::spirit::_pass;
std::wstring testChar(L"450");
auto f = testChar.begin(), l = testChar.end();
unsigned pVal[2] = {0, 0};
qi::uint_parser<unsigned, 10, 1, 1> uint1_p;
bool retVal = qi::parse(f, l, uint1_p[_pass = _1 <= (unsigned)4] >> qi::uint_, pVal[0], pVal[1]);
return 0;
}
在这种情况下是否最好始终投射?
在 Visual Studio 2015 年的基础上使用 Boost 1.61.0
您正在将 uint1_p
解析器的属性与 4
进行比较。 uint1_p{}
的属性类型是 unsigned
,因此您将 unsigned
与 decltype(4)
进行比较,即 int
.
进行混合符号比较是危险的,编译器会对此发出警告。问题是无符号整数算法是 "contagious",这意味着 4
将被提升为无符号整数,而不是相反。如果你有,这是一个风险。 _1 >= 0
因为它永远不会是假的。
令人印象深刻"error novel"是因为警告出现在语义动作评估的Spirit代码深处。如果你写一些更简单的东西,你会得到同样的信息,比如:
#include <iostream>
int main() {
for (unsigned i = 10; i >= 0; --i)
std::cout << i << " ";
}
此程序在 10 次迭代后不会停止。编译器(在本例中为 GCC)警告:
prog.cc:3:29: warning: comparison of unsigned expression >= 0 is always true [-Wtype-limits]
for (unsigned i = 10; i >= 0; --i)
~~^~~~
Q. SHOULD I ALWAYS CAST?
是的。和不。您应该永远不要 使用您编写的 C 风格转换¹。你可以考虑static_cast<unsigned>(4)
。但我会简单地写 4u
:
bool retVal = qi::parse(f, l, uint1_p[_pass = (_1 <= 4u)] >> qi::uint_, pVal[0], pVal[1]);
¹ 请参阅示例
- https://www.securecoding.cert.org/confluence/display/cplusplus/EXP05-CPP.+Do+not+use+C-style+casts
- What is the difference between static_cast<> and C style casting?