初始化Consts的问题

时间:2010-04-15 12:57:15

标签: c++ aix xlc

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

错误在哪里?

#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。

5 个答案:

答案 0 :(得分:3)

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

答案 1 :(得分:2)

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

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

答案 2 :(得分:1)

这将是一个猜测为什么const很重要,但人们可以做出合理的假设。

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

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

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

现在,您将错误的格式说明符传递给printf(...),即%u而不是%ld。这可能导致printf(...)查找错误的位置以获取其数据 - 可能在寄存器而不是堆栈中,或者相反。这样的行动可能会导致非常令人惊讶的结果。例如,printf(...)可能会遇到未覆盖的result或某些寄存器中的随机旧值。似乎在非const情况下它恰好找到了正确的值(即使它可能在错误的位置找到它),而在const情况下printf(...)只是找到了垃圾。

答案 3 :(得分:0)

可能没有关系,但要小心:printf的%u说明符表示无符号整数,但是你传递的是有符号整数。

答案 4 :(得分:0)

g ++处理这个很好,并没有提到警告。它确实抱怨printf。您应该使用%lu进行长整数。甚至更好,使用%ld或强制转换为(unsigned long int)。