C++ 这是不可避免的有符号和无符号整数比较吗?

C++ 这是不可避免的有符号和无符号整数比较吗?,c++,casting,unsigned,signed,C++,Casting,Unsigned,Signed,可能不会,但我想不出一个好的解决办法。我还不是C++专家。 最近,我在一个项目中将许多ints转换为unsigned ints。基本上,所有不应该是负数的东西都是不带符号的。这消除了MinGW的许多警告: 警告:有符号和无符号整数表达式之间的比较[-Wsign compare] 我喜欢它。它使程序更健壮,代码更具描述性。然而,有一个地方它们仍然存在。看起来是这样的: unsigned int subroutine_point_size = settings->get<unsigned

可能不会,但我想不出一个好的解决办法。我还不是C++专家。

最近,我在一个项目中将许多
int
s转换为
unsigned int
s。基本上,所有不应该是负数的东西都是不带符号的。这消除了MinGW的许多警告:

警告:有符号和无符号整数表达式之间的比较[-Wsign compare]

我喜欢它。它使程序更健壮,代码更具描述性。然而,有一个地方它们仍然存在。看起来是这样的:

unsigned int subroutine_point_size = settings->get<unsigned int>("subroutine_point_size");
...
for(int dx = -subroutine_point_size;dx <= subroutine_point_size;dx++) //Fill pixels in the point's radius.
{
    for(int dy = -subroutine_point_size;dy <= subroutine_point_size;dy++)
    {
        //Do something with dx and dy here.
    }
}
unsigned int subroutine\u point\u size=settings->get(“subroutine\u point\u size”);
...
对于(int dx=-子程序\u点\u大小;dx而不是当前

for(int dx=-子程序\u点\u大小;dx而不是当前值


for(int dx=-subroutine\u point\u size;dx将变量转换为
long int
long long int
类型,同时给出无符号int(0..2^32-1)的范围和符号。

将变量转换为
long int
long long long int
类型,同时给出无符号int(0..2^32-1)的范围然后签字。

你犯了一个大错误

基本上,您喜欢名称“unsigned”,并希望它表示“notnegative”,但这不是与类型相关联的语义

考虑以下陈述:

将有符号整数和无符号整数相加,结果为无符号

显然,如果你把“无符号”这个词看作“不是否定的”,这是没有意义的,但这就是语言所做的:把3加在未签名的值2上,你将得到一个巨大的无意义的数字,而不是正确的答案——1。

实际上,使用容器大小的无符号类型的选择是C++的设计错误,因为向后兼容性,现在已经太晚了,无法修复。通过这种方式,它的发生原因与“非负性”无关,而只是在计算机这么小的时候使用第十六位的能力。(即,能够使用65535个元素而不是32767)。即使在那时,我也不认为错误语义的代价是值得的(如果32767现在还不够,那么65535很快就不够了)

不要重复程序中的相同错误……名称不相关,重要的是语义,而对于<代码>未签名< /C> > C和C++,它是“n=2K的Zn模环成员”。


您不希望容器的大小成为模环的成员,是吗?

您犯了一个大错误

基本上,您喜欢名称“unsigned”,并希望它表示“notnegative”,但这不是与类型相关联的语义

考虑以下陈述:

将有符号整数和无符号整数相加,结果为无符号

显然,如果你把“无符号”这个词看作“不是否定的”,这是没有意义的,但这就是语言所做的:把3加在未签名的值2上,你将得到一个巨大的无意义的数字,而不是正确的答案——1。

实际上,使用容器大小的无符号类型的选择是C++的设计错误,因为向后兼容性,现在已经太晚了,无法修复。通过这种方式,它的发生原因与“非负性”无关,而只是在计算机这么小的时候使用第十六位的能力。(即,能够使用65535个元素而不是32767)。即使在那时,我也不认为错误语义的代价是值得的(如果32767现在还不够,那么65535很快就不够了)

不要重复程序中的相同错误……名称不相关,重要的是语义,而对于<代码>未签名< /C> > C和C++,它是“n=2K的Zn模环成员”。


您不希望容器的大小成为模环的成员。是吗?

首先,在不知道将存储在变量中的值的范围的情况下,您关于将有符号变量更改为无符号变量的声明是没有根据的-在某些情况下,该声明是错误的

其次,编译器不会仅在变量更改时发出警告(我假设调用模板函数,如
settings.get()
)未签名。它警告您的表达式同时包含有符号变量和无符号变量。编译器通常会对此类表达式发出警告,因为在实践中,它们更可能指示编程错误或可能涉及程序员可能未预料到的某些行为(例如,未定义行为的实例、预期会出现负面结果但会出现大量正面结果的表达式等)

经验法则是,如果您需要同时包含有符号和无符号类型的表达式,最好对所有相关变量进行有符号处理。虽然存在不需要经验法则的例外情况,但如果您了解如何确定,您就不会问这个问题


在此基础上,我建议最合适的操作是取消更改。

首先,在不知道将存储在变量中的值的范围的情况下,您声称将有符号变量更改为无符号变量是没有根据的-在某些情况下,这种说法是错误的

其次,编译器不会仅在变量更改时发出警告(我假设调用模板函数,如
settings.get()
)未签名。它警告您的表达式同时包含有符号变量和无符号变量。编译器通常会对此类表达式发出警告,因为在实践中,它们更可能指示编程错误或可能涉及程序员可能未预料到的某些行为(例如,未定义行为的实例、预期结果为负面但p值较大的表达式)
for(int dx = -subroutine_point_size;dx <= subroutine_point_size;dx++) //Fill pixels in the point's radius.
for(int dx = -int(subroutine_point_size);dx <= int(subroutine_point_size);dx++) //Fill pixels in the point's radius.