【问题标题】:Problem with Initializing Consts初始化常量的问题
【发布时间】:2011-02-08 09:04:21
【问题描述】:

此代码在 xlC 8.0(在 AIX 5.3 上)中编译时会产生错误的结果。 它应该打印12345,而是打印804399880。 删除result 前面的const 可使代码正常工作。

错误在哪里?

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

long int foo(std::string input)
{
        return strtol(input.c_str(), NULL, 0);
}

void bar()
{
        const long int result = foo("12345");
        printf("%u\n", result);
}

int
main()
{
        bar();
        return 0;
}

编译命令:

/usr/vacpp/bin/xlC example.cpp -g

编辑:将上面的 printf 格式字符串更改为 "%ld\n" 没有帮助。 编辑 2:使用的 AIX 版本是 5.3,而不是 6.1。

【问题讨论】:

  • 可能是编译器问题...它适用于 VS2008 和 gcc (mingw)
  • 在 AIX 5.3 上使用 XL C/C++ 8.0 为我工作。很有趣。
  • @Fred 你用的是什么版本的 xlc? (xlC -qversion) 我使用的是 08.00.0000.0000。
  • IBM XL C/C++ Enterprise Edition V8.0 for AIX 版本:08.00.0000.0016

标签: c++ aix xlc


【解决方案1】:

g++ 处理得很好并且没有提及警告。它确实抱怨 printf。您应该将 %lu 用于 long int。或者甚至更好,使用 %ld 或强制转换为 (unsigned long int)。

【讨论】:

  • 或者只使用 iostream 并避免整个问题。
  • 是的,%ld 会更好,但是 g++ 可以使用 %lu。它不关心数字被解释错误,只要它是正确的长度。
【解决方案2】:

为什么 const 很重要有点猜测,但可以做出合理的假设。

具有块范围的变量,例如result,可以分配到寄存器或放入堆栈。影响寄存器是否使用的因素有很多。在这种情况下,const 很可能很重要。最后,编译器有权使用它认为最好的东西。

同样,函数的参数可以在寄存器或堆栈中传递。由于函数通常是单独编译的,它们的接口(即声明)决定了哪个参数去哪里。 printf(...) 是一种特殊情况,因为它可以使用不同类型的参数调用。因此,哪些数据最终会发生变化,您需要告诉 printf(...) 会发生什么。

现在,当将变量传递给函数时,编译器通常必须复制它。从一个寄存器到堆栈,一个寄存器到另一个,等等,可能有很多变化。正如我所指出的,源位置可能会根据const 的存在与否而有所不同。

现在,您将错误的格式说明符传递给printf(...),即%u 而不是%ld。这可能导致 printf(...) 在错误的位置查找数据 - 可能在寄存器而不是堆栈中,或者相反。这样的行动会导致相当惊人的结果。例如,printf(...) 可能会偶然发现您未复制的result,或某些寄存器中的随机旧值。似乎在非 const 情况下它碰巧找到了正确的值(即使它可能在错误的地方找到它),而在 const 情况下 printf(...) 只是找到垃圾。

【讨论】:

  • 谢谢,但代码是 32 位的,所以“%u”和“%ld”大小相同。
【解决方案3】:

这是标记为 c++,那么当你使用 cout 而不是 printf 时会发生什么?

看起来问题是你告诉 printf 打印一个 unsigned int 然后发送一个有符号的 long int 来实际打印。很可能内存布局不同,printf 无法理解您真正想要做什么。

【讨论】:

    【解决方案4】:

    可能不相关,但要小心:printf 的 %u 说明符表示一个无符号整数,但您传递的是一个有符号整数。

    【讨论】:

      【解决方案5】:

      xlC 10.0 工作正常,似乎是编译器错误

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-10
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多