【发布时间】:2012-06-20 22:57:02
【问题描述】:
#include <limits.h>
#include <stdio.h>
int main() {
long ival = 0;
printf("ival: %li, min: %i, max: %i, too big: %i, too small: %i\n",
ival, INT_MIN, INT_MAX, ival > INT_MAX, ival < INT_MIN);
}
这给出了输出:
ival: 0, min: -2147483648, max: 2147483647, too big: 0, too small: 1
这怎么可能?
(实际上,我在getargs.c:convertsimple 中遇到了 CPython 2.7.3 中的这个问题/错误。如果您在case 'i' 中查找代码,则检查ival < INT_MIN 始终正确对我来说。另见test case source with further references。)
好吧,我现在测试了几个不同的编译器。为 x86 编译的 GCC/Clang 都返回预期值(太小:0)。为 armv7 编译时,意外输出来自 Xcode 工具链中的 Clang。
如果你想重现:
这是确切的编译命令:/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/clang -arch armv7 -isysroot /Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS5.1.sdk test-int.c
这是 Xcode 4.3.2。
我将生成的 a.out 复制到我的 iPhone 上并执行它。
如果有人对此生成的汇编代码感兴趣:
.section __TEXT,__text,regular,pure_instructions
.section __TEXT,__textcoal_nt,coalesced,pure_instructions
.section __TEXT,__const_coal,coalesced
.section __TEXT,__picsymbolstub4,symbol_stubs,none,16
.section __TEXT,__StaticInit,regular,pure_instructions
.syntax unified
.section __TEXT,__text,regular,pure_instructions
.globl _main
.align 2
.code 16
.thumb_func _main
_main:
push {r7, lr}
mov r7, sp
sub sp, #20
movw r0, #65535
movt r0, #32767
movs r1, #0
movt r1, #0
str r1, [sp, #16]
str r1, [sp, #12]
ldr r1, [sp, #12]
ldr r2, [sp, #12]
cmp r2, r0
movw r0, #0
it gt
movgt r0, #1
and r0, r0, #1
ldr r2, [sp, #12]
cmn.w r2, #-2147483648
movw r2, #0
it lt
movlt r2, #1
and r2, r2, #1
mov r3, sp
str r2, [r3, #4]
str r0, [r3]
mov.w r2, #-2147483648
mvn r3, #-2147483648
movw r0, :lower16:(L_.str-(LPC0_0+4))
movt r0, :upper16:(L_.str-(LPC0_0+4))
LPC0_0:
add r0, pc
blx _printf
ldr r1, [sp, #16]
str r0, [sp, #8]
mov r0, r1
add sp, #20
pop {r7, pc}
.section __TEXT,__cstring,cstring_literals
L_.str:
.asciz "ival: %li, min: %i, max: %i, too big: %i, too small: %i\n"
.subsections_via_symbols
【问题讨论】:
-
可能是选角怪癖?有可能将 INT_MIN 转换为 long 并且没有正确处理标志?或相反亦然? O.o
-
@Albert 很有趣,我得到了
ival: 0, min: -2147483648, max: 2147483647, too big: 0, too small: 0 -
我认为 printf 没有 %i 格式。你可能想要 %d。将 printf 等 varargs 函数的参数显式转换为 int 是一个好习惯。 (在这种情况下不需要,因为 (a>b) 的值默认为 int 类型)
-
@wildplasser:是的,
printf有一个%i格式。与%d相同。 -
糟糕。我的错。我认为这是以前扩展的遗留物。