为什么−1>大小(int)?

发布于 2024-09-07 01:17:27 字数 618 浏览 6 评论 0原文

考虑下面的代码:

template<bool> class StaticAssert;
template<> class StaticAssert<true> {};
StaticAssert< (-1 < sizeof(int)) > xyz1; // Compile error
StaticAssert< (-1 > sizeof(int)) > xyz2; // OK

为什么 -1 > sizeof(int) 是吗?

  1. 是否真的将 -1 提升为 unsigned(-1) 然后 unsigned(-1) > sizeof(int)
  2. -1 > 是真的吗? sizeof(int) 相当于 -1 > size_t(4) 如果 sizeof(int) 是 4。如果是这样,为什么 -1 > > size_t(4) 是假的?

这个C++标准符合吗?

Consider the following code:

template<bool> class StaticAssert;
template<> class StaticAssert<true> {};
StaticAssert< (-1 < sizeof(int)) > xyz1; // Compile error
StaticAssert< (-1 > sizeof(int)) > xyz2; // OK

Why is -1 > sizeof(int) true?

  1. Is it true that -1 is promoted to unsigned(-1) and then unsigned(-1) > sizeof(int).
  2. Is it true that -1 > sizeof(int) is equivalent to -1 > size_t(4) if sizeof(int) is 4. If this is so why -1 > size_t(4) is false?

Is this C++ standard comformant?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

南…巷孤猫 2024-09-14 01:17:28

这很简单,也很悲伤。在C/C++中:

  1. 大多数时候,无符号整数类型具有模整数的语义(它们表示等价类)
  2. 无符号整数类型的比较具有通常整数排序的语义,因此1U < 2U(IOW 0U 是最小的无符号值)
  3. sizeof 的类型为 size_t
  4. size_t 是无符号整数类型
  5. Point (1) 意味着涉及有符号和无符号整数的混合算术计算是在无符号、模算术中完成的:这是不违反“无符号平均模数”规则的唯一可能性。将整数转换为与其等价的整数的等价类是很简单的。 (反之则需要选择一个整数来表示等价类。)
  6. 点 (5) 意味着 -1 -1 -1 -1 1U 被解释为 unsigned(-1) 1U,并且 unsigned(-1) = - 1U,并且显然 - 1U 1U,所以-1 < 1U 是正确的。
  7. 点 (1,3,4) 暗示 sizeof Something 充当(大部分)作为等效类(!!!)。
  8. 所有这些都意味着 -1 sizeof Something

结论:这是从 C 继承的设计错误。

规则:

仅使用无符号类型进行模算术、位操作(&|^<<>>~ 运算符) 、字节操作(unsigned char 在 C/C++ 中表示“字节”)和字符(unsigned char 在 C/C++ 中表示字符)。

不要使用无符号类型进行算术运算。

如果函数需要一个永远不应该为负数的整数值,请采用有符号整数,并可以选择在函数中检查该值是否在范围内。

It's simple and sad. In C/C++:

  1. most of the time, unsigned integer types have the semantic of modular integers (they represent equivalence classes)
  2. comparisons of unsigned integer types have the semantic of usual integer ordering, so that 1U < 2U (IOW 0U is the smallest unsigned value)
  3. sizeof has type size_t
  4. size_t is an unsigned integer type
  5. Point (1) implies that mixed arithmetic computations involving a signed and an unsigned integer are done in unsigned, modular arithmetic: this is the only possibility without violating "unsigned mean modular" rule. It's trivial to convert an integer to the equivalence class of integers equivalent to it. (Whereas going the other way requires the choice of an integer to represent the equivalence class.)
  6. Point (5) implies that -1 < 1U is interpreted as unsigned(-1) < 1U, and unsigned(-1) = - 1U, and obviously - 1U < 1U, so -1 < 1U is true.
  7. Points (1,3,4) imply that sizeof something acts (mostly) as an equivalent class (!!!).
  8. All this imply that -1 < sizeof something

The conclusion: this is a design error inherited from C.

Rule:

Only use unsigned types for modular arithmetic, bits manipulations (&, |, ^, <<, >>, ~ operators), byte manipulations (unsigned char means "byte" in C/C++), and characters (unsigned char means character in C/C++).

Do not use unsigned types to do arithmetic.

If a function expects an integer value that should never be negative, take a signed integer, and optionally check in the function that the value is in range.

三五鸿雁 2024-09-14 01:17:27

以下是标准(ISO 14882)如何解释 abort -1 > sizeof(int)

关系运算符“>”定义于 5.9 (expr.rel/2)

通常的算术转换是
对算术或操作数执行
枚举类型。 ...

通常的算术转换定义在 5 (expr/9)

... 该模式称为通常的算术转换,其定义如下:

  • 如果任一操作数的类型为 long
    double, ...
  • 否则,如果任一操作数为 dobule, ...
  • 否则,如果任一操作数为 float,...
  • 否则,应对两个操作数执行整数提升。
  • ...

积分促销在 4.5 (conv.prom/1) 中定义

char 类型的右值,有符号 char,
unsigned char、short int 或 unsigned
短整型可以转换为
如果 int 可以,则为 int 类型的右值
代表源的所有值
类型;否则,源右值可以
转换为类型的右值
无符号整数。

sizeof的结果在5.3.3中定义(expr.sizeof/6)

结果是一个常量类型
尺寸_t

size_t 在 C 标准(ISO 9899)中定义,它是无符号整数类型

所以对于 -1 > sizeof(int),>触发通常的算术转换。通常的算术转换将 -1 转换为 unsigned int,因为 int 无法表示 size_t 的所有值。 -1 变成一个非常大的数字,具体取决于平台。所以 -1 > sizeof(int)true

The following is how standard (ISO 14882) explains abort -1 > sizeof(int)

Relational operator `>' is defined in 5.9 (expr.rel/2)

The usual arithmetic conversions are
performed on operands of arithmetic or
enumeration type. ...

The usual arithmetic conversions is defined in 5 (expr/9)

... The pattern is called the usual arithmetic conversions, which are defined as following:

  • If either operand is of type long
    double, ...
  • Otherwise, if either operand is dobule, ...
  • Otherwise, if either operand is float, ...
  • Otherwise, the integral promotions shall be performed on both operands.
  • ...

The integral promotions is defined in 4.5 (conv.prom/1)

An rvalue of type char, signed char,
unsigned char, short int, or unsigned
short int can be converted to an
rvalue of type int if int can
represent all the values of the source
type; otherwise, the source rvalue can
be converted to an rvalue of type
unsigned int.

The result of sizeof is defined in 5.3.3 (expr.sizeof/6)

The result is a constant of type
size_t

size_t is defined in C standard (ISO 9899), which is unsigned integer type.

So for -1 > sizeof(int), the > triggers usual arithmetic conversions. The usual arithmetic conversion converts -1 to unsigned int because int cannot represent all the value of size_t. -1 becomes a very large number depend on platform. So -1 > sizeof(int) is true.

蓝戈者 2024-09-14 01:17:27

因为 unsigned 比有符号更强,并且 -1 从 size_t 开始转换为无符号值,所以实际上 -1 == 0xFFFFFFFF > 4

根据 C++ 标准,它应该是这样工作的

Because unsigned is stronger then signed and -1 converted to unsigned value as of size_t , so actually -1 == 0xFFFFFFFF > 4

This is how it should work according to C++ standard

挽梦忆笙歌 2024-09-14 01:17:27

因为 -1 被转换为 size_t 并且这是一个无符号数据类型 - 所以 (size_t)-1 == 4294967295 (在 32 位系统上)它肯定大于 4

例如,如果您将 -Wall 添加到 gcc 设置中,您会收到一条警告,提示您正在比较有符号和无符号数据类型

because -1 gets casted to size_t and this is an unsigned data type - so (size_t)-1 == 4294967295 (on a 32bit system) which is definitely larger than 4

if you add -Wall to the gcc settings for example you get a warning that you are comparing a signed and an unsigned data type

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文