答案可能不会使我从专业上受益,但我很想知道:为什么这两个简单的C++循环都不都是无限的?
循环1(无限)
constexpr unsigned short max = USHRT_MAX;
for (signed short ss = 0; ss < max; ++ss);
循环2(非无限)constexpr unsigned int max = UINT_MAX;
for (signed int si = 0; si < max; ++si);
循环1的输出显示ss递增至SHRT_MAX
,然后递增至-SHRT_MAX
-1,再递增至-1(或USHRT_MAX
),并无限重复该循环。循环2的输出显示si递增至
INT_MAX
,然后递增至-INT_MAX - 1
,然后递增至-1(或UINT_MAX
),然后停止。有人可以提供我需要的有关这些整数类型如何工作的缺失信息吗(隐式转换,实现奇数等)?
最佳答案
请参阅Does i++ invoke undefined behavior for signed types smaller than int in case of overflow?,以获取对下一段的必要更正。
它的UBsigned short ss = 0; ss < max; ++ss)
问题是++ss
类似于ss = ss+ 1
,这是SHRT_MAX < INT_MAX
时分配中实现的定义行为。 ss+1
定义明确,但是分配存在争议。无论采用哪种实现,ss
都将永远不会达到USHRT_MAX
。当SHRT_MAX < USHRT_MAX
时,循环是无限的。signed int si = 0; si < max; ++si
是未定义的行为(UB),因为++ss
在达到ss < max
的限制之前会导致带符号的整数溢出(UB)。
包装++si
时将si == INT_MAX
的通用UB打包为si == INT_MIN
。最终si == -1
和si < max;
就像(unsigned)-1 < max
一样,它为false,从而停止了循环。
第二次循环是不确定的。为了肯定地表现,将需要定义的行为。
如果short
具有与int
相同的大小,则两者均为UB-但仍然不需要表现相同。
推荐:
constexpr unsigned short max = USHRT_MAX;
// vv
for (unsigned short ss = 0; ss < max; ++ss);
和constexpr unsigned int max = UINT_MAX;
// vv
for (unsigned int si = 0; si < max; ++si);
关于c++ - 为什么这两个简单循环都不是无限的?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/63043910/