当size_t溢出时,"<"和">"运算符是否正常工作?

Mak*_*con 3 c printf overflow size-t operator-keyword

我正在研究一个更新20年代码的项目,其中许多问题都与整数溢出有关.我想确保我正确测试溢出,所以我写了一个测试程序.它的输出让我感到沮丧.这里是:

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>

int main (void) {

   size_t largerNum,Num;

   largerNum = 12;
   Num = UINT_MAX;

   printf("largerNum = %u\nNum = %u\nNum + 1 = %u\n", largerNum    , Num, Num + 1);

   largerNum = Num + 1;

   printf("largerNum now = %u\n", largerNum);

   if(largerNum < Num ){
      printf("largerNum overflowed to %u\n", largerNum);
   }
   else {
      printf("largerNum did not overflow: %u\n", largerNum);
   }

   printf("Is (0 < UINT_MAX)?\n");

   (0 < UINT_MAX)?printf("YES\n"):printf("NO\n");

   printf("Is (largerNum < Num)?\n");

   (largerNum < Num)?printf("YES\n"):printf("NO\n");

   return 0;
}
Run Code Online (Sandbox Code Playgroud)

它的输出:

[afischer@susm603 /home/afischer/Fischer_Playground/overflowTest]$ main
largerNum = 12
Num = 4294967295
Num + 1 = 0
largerNum now = 0
largerNum did not overflow: 0
Is (0 < UINT_MAX)?
YES
Is (largerNum < Num)?
NO
Run Code Online (Sandbox Code Playgroud)

我在这里这里看了一些其他帖子并阅读了这篇论文,但它还没有让输出更清晰.有谁看过这个吗?

编辑:我得到了它的更改,当工作size_tunsigned long,这不应该做任何事情.

  6 int main (void) {
  7 
  8    unsigned long largerNum,Num;
  9 
 10    largerNum = 12;
 11    Num = UINT_MAX;
 12 
 13    printf("largerNum = %u\nNum = %u\nNum + 1 = %u\n", largerNum    , Num, Num + 1);
 14 
 15    largerNum = Num + 2;
 16 
 17    printf("largerNum now = %u\n", largerNum);
 18 
 19    if(largerNum < Num ){
 20       printf("largerNum overflowed to %u\n", largerNum);
 21    }
 22    else {
 23       printf("largerNum did not overflow: %u\n", largerNum);
 24    }
 25 
 26    printf("Is (0 < UINT_MAX)?\n");
 27 
 28    (0 < UINT_MAX)?printf("YES\n"):printf("NO\n");
 29 
 30    printf("Is (largerNum < Num)?\n");
 31 
 32    (largerNum < Num)?printf("YES\n"):printf("NO\n");
 33 
 34 
 35    printf("largerNum = %u\n", largerNum);
 36    printf("Num = %u\n", Num);
 37 
 38    return 0;
 39 }
Run Code Online (Sandbox Code Playgroud)

输出:

[afischer@susm603 /home/afischer/Fischer_Playground/overflowTest]$ main
largerNum = 12
Num = 4294967295
Num + 1 = 0
largerNum now = 1
largerNum overflowed to 1
Is (0 < UINT_MAX)?
YES
Is (largerNum < Num)?
YES
largerNum = 1
Num = 4294967295
Run Code Online (Sandbox Code Playgroud)

EDIT2:

在阅读了一些评论后,我将'UINT_MAX'替换为'ULONG_MAX',并且三元运算符正常运行.然后我将'size_t'改为'unsigned long'.它仍然可以正常工作.对我来说奇怪的是,在我的机器上,'size_t','unsigned int'和'unsigned long'都是相同的字节数,'UINT_MAX'和'ULONG_MAX'是相同的值,但是那个三元运算符尽管一切都是一样的,但仍会失败.也许它不一样?这扰乱了我对C的理解.

对于那些感兴趣的人,工作代码:

  6 int main (void) {
  7    /* Can be size_t or unsigned long */
  8    size_t largerNum,Num;
  9 
 10    largerNum = 12;
 11    Num = ULONG_MAX;
 12 
 13    printf("largerNum = %u\nNum = %u\nNum + 1 = %u\n", largerNum    , Num, Num + 1);
 14 
 15    largerNum = Num + 2;
 16 
 17    printf("largerNum now = %u\n", largerNum);
 18 
 19    if(largerNum < Num ){
 20       printf("largerNum overflowed to %u\n", largerNum);
 21    }
 22    else {
 23       printf("largerNum did not overflow: %u\n", largerNum);
 24    }
 25 
 26    printf("Is (0 < ULONG_MAX)?\n");
 27 
 28    (0 < ULONG_MAX)?printf("YES\n"):printf("NO\n");
 29 
 30    printf("Is (largerNum < Num)?\n");
 31 
 32    (largerNum < Num)?printf("YES\n"):printf("NO\n");
 33 
 34    
 35    printf("largerNum = %u\n", largerNum);
 36    printf("Num = %u\n", Num);
 37    
 38    return 0;
 39 }
Run Code Online (Sandbox Code Playgroud)

输出:

[afischer@susm603 /home/afischer/Fischer_Playground/overflowTest]$ main
largerNum = 12
Num = 4294967295
Num + 1 = 0
largerNum now = 1
largerNum overflowed to 1
Is (0 < ULONG_MAX)?
YES
Is (largerNum < Num)?
YES
largerNum = 1
Num = 4294967295
Run Code Online (Sandbox Code Playgroud)

最终编辑:

在阅读了更多评论之后,我发现我的printf()陈述是错误的.谢谢大家的帮助,现在一切都变得更有意义了.= d

最终代码:

  6 int main (void) {
  7 
  8    unsigned long largerNum,Num;
  9 
 10    largerNum = 12;
 11    Num = ULONG_MAX;
 12 
 13    printf("largerNum = %zu\nNum = %zu\nNum + 1 = %zu\n", larger    Num, Num, Num + 1);
 14 
 15    largerNum = Num + 2;
 16 
 17    printf("largerNum now = %zu\n", largerNum);
 18 
 19    if(largerNum < Num ){
 20       printf("largerNum overflowed to %zu\n", largerNum);
 21    }
 22    else {
 23       printf("largerNum did not overflow: %zu\n", largerNum);
 24    }
 25 
 26    printf("Is (0 < ULONG_MAX)?\n");
 27 
 28    (0 < ULONG_MAX)?printf("YES\n"):printf("NO\n");
 29 
 30    printf("Is (largerNum < Num)?\n");
 31 
 32    (largerNum < Num)?printf("YES\n"):printf("NO\n");
 33 
 34 
 35    printf("largerNum = %zu\n", largerNum);
 36    printf("Num = %zu\n", Num);
 37 
 38    return 0;
 39 }
Run Code Online (Sandbox Code Playgroud)

最终产出:

[afischer@susm603 /home/afischer/Fischer_Playground/overflowTest]$ main
largerNum = 12
Num = 18446744073709551615
Num + 1 = 0
largerNum now = 1
largerNum overflowed to 1
Is (0 < ULONG_MAX)?
YES
Is (largerNum < Num)?
YES
largerNum = 1
Num = 18446744073709551615
Run Code Online (Sandbox Code Playgroud)

Pra*_*ian 6

我的猜测是你的平台有64位size_t,并且你使用了错误的格式说明符来打印a size_t,这是未定义的行为并导致误导输出.

打印size_ts,请%zu在gcc和clang以及%IuMSVC上使用.或者忘记所有这些并用于std::cout打印结果.

%Iu在VS2015上使用,我在64位编译器上获得的输出是

largerNum = 12
Num = 4294967295
Num + 1 = 4294967296
largerNum now = 4294967296
largerNum did not overflow: 4294967296
Is (0 < UINT_MAX)?
YES
Is (largerNum < Num)?
NO
Run Code Online (Sandbox Code Playgroud)