奇怪的C函数返回变量类型行为

时间:2013-10-07 20:25:56

标签: c types return

我遇到了一个我不明白的行为。 我希望有趣的是返回2字节的val。 我创建一个4字节的var来做一些处理并返回变量。 我的假设是变量被隐式转换为short。 但是,似乎返回的值不是2字节,因为printf fun打印的值大于2 ^ 16,除非我在fun()之前放置(short)。 那是为什么?

short fun()
{
long var = 2<<20;
return var;
}

printf("%i", fun());

3 个答案:

答案 0 :(得分:3)

printf等变量函数在其操作数上执行所谓的默认参数提升。特别是,比int更窄的整数(例如short)在传递到可变函数时会自动扩展到int

解决此问题的一种方法是使用h长度修饰符,即“即使您正在处理int值,也假设它实际上是short”。然后,printf会在格式化输出之前将值缩小回short。例如:

printf("%hi", fun());

答案 1 :(得分:1)

10开始,左移20到1000000000000000000000超出短路范围并将其传递给获得可变参数的函数(...)

当printf(和其他可变函数)查看该值时,它基本上只是一个内存位置,它使用格式说明符将其强制转换回原始类型。以下是它基本上做的宏观示例:

#define va_arg(ap,type)     (*(type *)(((ap)+=(((sizeof(type))+(sizeof(int)-1)) \
                            & (~(sizeof(int)-1))))-(((sizeof(type))+ \
                            (sizeof(int)-1)) & (~(sizeof(int)-1)))))

如果您添加了一个格式说明符,将其转换为short,则可以看到已转换的short。除此之外,保持(简短) - 你的乐趣()。

答案 2 :(得分:1)

return var;中,var的值将转换为函数的返回类型,即short。由于该值超出了C实现中short的范围,因此存在溢出。 C规范没有定义当存在整数溢出时会发生什么。

尽管如此,这种行为有点奇怪。在printf调用中,许多C实现仅使用fun()中的16位,将它们提升为int,并将它们传递给printf。因此,尽管有溢出,输出仍为“0”。

在您的情况下可能发生的情况是,编译器通过简单地忽略它并将值保留在处理器寄存器中,将值转换为short(并使用相同的值)来实现转换为var注册以返回函数值)。 C标准允许这样做,因为如果寄存器中的long值在short域中,则在解释为short时,保持位不变会产生相同的值。如果long值超出short域,则无论发生什么都没关系,因为C标准没有定义必须发生的事情。

然后,寄存器的内容直接传递给printf作为参数。同样,这是有效的,因为如果值在short域中,它会产生正确的结果,如果var值不在short域中,则允许任何内容。

相关问题