下溢然后溢出无符号变量是不是很糟糕?

时间:2013-12-21 18:34:29

标签: c c89 size-t underflow

Kraaa。

我是编程学校的学生,他要求我们编写少于25行代码的C函数。所以,基本上,每一行都很重要。有时候,我需要缩短这样的作业:

#include <stddef.h>
#include <stdio.h>

#define ARRAY_SIZE  3

int     main(void)
{
    int     nbr_array[ARRAY_SIZE] = { 1, 2, 3 };
    size_t  i;

    i = -1;
    while (++i < ARRAY_SIZE)
        printf("nbr_array[%zu] = %i\n", i, nbr_array[i]);
    return (0);
}

此代码的重要部分是名为size_t的{​​{1}}计数器。为了节省几行代码,我想在循环条件下预先增加它。但是,在C标准将i定义为无符号类型的情况下,我基本上在这里做的是使size_t变量(从0变为非常大的值)下溢,然后溢出一次(来自那个大值为0)。

我的问题如下:无论不良做法是否需要缩短我们的代码,设置iunsigned)变量是否安全到-1然后在每次迭代时预先递增以浏览数组?

谢谢!

3 个答案:

答案 0 :(得分:4)

您的计划的i = -1;部分没问题。

-1转换为无符号整数类型在C中定义,并产生一个值,如果递增,则结果为零。

这就是说,你没有获得与惯用语for (i=0; i<ARRAY_SIZE; i++) …相关的任何代码。

您的%zi格式可能应为%zu

答案 1 :(得分:1)

无符号算术永远不会“溢出/下溢”(至少在标准谈论有符号算术溢出的未定义行为的方式)。所有无符号算术实际上都是modular arithmetic,因此是安全的(即它本身不会导致未定义的行为)。

答案 2 :(得分:1)

准确地说,C标准保证了两件事:

  • 明确定义了unsigned类型的任何整数转换(好像有符号数字表示为2补码)
  • unsigned整数的溢出/下溢定义明确(模数运算为2 ^ n)

由于size_t是无符号类型,因此您没有做任何不好的事情。