【问题标题】:Function returns int but getting strange behavior函数返回 int 但出现奇怪的行为
【发布时间】:2015-12-22 21:16:49
【问题描述】:

我写了一些代码来计算一个单词中的位数。当我printf() 计数时,它按预期打印 32,但是当我将相同的代码粘贴在函数中并打印返回值时,它给了我一些疯狂的大数字。

然后我将代码复制/粘贴回main() 打印计数并同时打印我的函数的返回值,嘿,他们都给了我 32 但如果我随后注释掉 main() 我的函数中的代码再次打印大数字。

有人知道为什么会这样吗?

#include <stdio.h>

int wordlength();

int main() {

printf("%d", wordlength()); // prints 4195424 but
                          // if I uncomment the code below
                          // it then prints 32 like I want

//  int count;
//  unsigned int n = ~0;
// 
//  while( n != 0) {
//      n = n >> 1;
//      count++;
//  }
//  printf("\n%d", count); // prints 32 as expected

    return 0;
}

int wordlength() {

    int count;
    unsigned int n = ~0;

    while( n != 0) {
        n = n >> 1;
        count++;
    }

    return count;
}

【问题讨论】:

  • 你可以通过打印CHAR_BIT * sizeof(int)来避免这一切
  • 使用 -1 而不是 ~0 意味着您的代码甚至可以在深奥的平台上工作
  • @M.M 我不相信存在~0 不适用于无符号整数的系统?
  • @M.M 如果您要担心深奥的平台:OP 的方法在具有填充位的平台上可以正常工作,而您的乘法则不能。
  • @Lundin ~0u 是可移植的,但 (unsigned) ~0 仅在 ~0 评估为 -1 时表示相同的含义,即当二进制补码用于负数时。

标签: c function printf return-value


【解决方案1】:

在您的wordlength() 函数中,count 是一个自动局部范围变量,并且未显式初始化。因此,初始值是不确定的。

引用C11 标准,第 §6.7.9 章

如果具有自动存储持续时间的对象未显式初始化,则其值为 不定。 [...]

您很容易对其应用后增量。它调用undefined behavior

相关,附件§J.2,未定义行为的原因,

具有自动存储持续时间的对象的值在它被使用时使用 不确定。

因此,您的程序展示了 UB,并且根本不保证会产生任何有效结果。

解决方法:将count初始化为0。

FWIW,关于评论

// 如果我取消注释下面的代码
// 然后它会像我想要的那样打印 32

也是UB的结果。

【讨论】:

  • 哇,谢谢,真不敢相信我错过了。由于 main() 中的相同代码无需初始化为零即可工作,是否会自动初始化?
  • @ThusSpokeChris 不,它也是 UB。
【解决方案2】:

您必须将count 初始化为 0 或其他值,否则它将具有未定义的值。

【讨论】:

    猜你喜欢
    • 2013-10-04
    • 2019-07-05
    • 1970-01-01
    • 1970-01-01
    • 2013-10-28
    • 2012-06-21
    • 1970-01-01
    • 1970-01-01
    • 2013-10-14
    相关资源
    最近更新 更多