我将通过Andrew Koenig和Barbara E. Moo撰写的“Accelerated C ++”一书,我对第2章中的主要示例有一些疑问。代码可以总结如下,并且编译时没有警告/错误克++:
#include <string>
using std::string;
int main()
{
const string greeting = "Hello, world!";
// OK
const int pad = 1;
// KO
// int pad = 1;
// OK
// unsigned int pad = 1;
const string::size_type cols = greeting.size() + 2 + pad * 2;
string::size_type c = 0;
if (c == 1 + pad)
{;}
return 0;
}
但是,如果我将const int pad = 1;
替换为int pad = 1;
,g ++编译器将返回警告:
warning: comparison between signed and unsigned integer expressions [-Werror=sign-compare]
if (c == 1 + pad)
如果我用const int pad = 1;
替换unsigned int pad = 1;
,g ++编译器将不会返回警告。
我理解为什么g ++会返回警告,但我不确定以下三点:
unsigned int
与std::string::size_type
进行比较是否安全?在这种情况下,编译器不会返回警告,但我不确定它是否安全。const int pad = 1
发出警告。编译器是否自动将变量pad
转换为unsigned int
?const int pad = 1;
替换string::size_type pad = 1;
,但在我看来,变量pad
的含义并没有真正与字符串大小相关联。不过,在这种情况下,这是避免在比较中使用不同类型的最佳方法吗?答案 0 :(得分:2)
从编译器的角度来看:
所以问题的答案是:
unsigned int
和std::string::size_type
。unsinged int
。答案 1 :(得分:1)
如果您使用size_type
默认分配器(可能),那么size_t
实际上是size_t
。
[support.types] / 6 定义unsigned int
是
实现定义的无符号整数类型,其大小足以包含大小 以字节为单位的任何对象。
所以它在技术上并不保证是const int something = 2
,但我相信它在大多数情况下都是以这种方式定义的。
现在关于你的第二个问题:如果你使用size_t
,编译器会发现这个整数是a)从不为负数而b)永远不会改变,所以将这个变量与{{进行比较'总是安全的1}}。在某些情况下,编译器可以完全优化变量,并简单地用2
替换它的所有出现。
我会说,最好在任何地方使用size_type
,因为它更详细。
答案 2 :(得分:1)
比较有符号值和无符号值是“危险的”,因为当有符号值为负时,您可能无法得到预期的值(它可能表现为非常大的无符号值,因此a > b
给出{ {1}} true
时a = -1
的使用。b = 100
的使用有效,因为编译器知道值没有变化,因此可以说“好吧,这个值总是1,所以它在这里工作正常“)
只要您要比较的值适合const int
(在典型的机器上,略多于40亿)就可以了。
答案 3 :(得分:1)
编译器警告的是无符号和有符号整数类型的比较。这是因为有符号整数可以是负数,其含义是反直觉的。这是因为签名在比较之前转换为无符号,这意味着负数将比正数更好。
使用unsigned int以便与std :: string :: size_type进行比较是否安全?在这种情况下,编译器不会返回警告,但我不确定它是否安全。
是的,它们都是无符号的,然后语义就是预期的。如果它们的范围不同,则较窄的转换为更宽的类型。
为什么编译器没有给出原始代码const int pad = 1的警告。编译器是否自动将变量pad转换为unsigned int?
这是因为编译器的构造方式。编译器解析并在某种程度上优化代码,然后发出警告。重要的一点是,此时警告被认为是编译器发现有符号整数为1
,然后可以安全地与无符号整数进行比较。
我也可以替换const int pad = 1; by string :: size_type pad = 1;,但在我看来,变量pad的含义并没有真正链接到字符串大小。在这种情况下,这是否是避免在比较中使用不同类型的最佳方法?
如果您不希望它保持不变,那么最佳解决方案可能是使其至少成为无符号整数类型。但是,您应该知道普通整数类型和大小之间没有保证关系,例如unsigned int
可能更窄,更宽或等于size_t
和size_type
(后者也可能不同)。