#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);
}
これは、出力が得られます。奇妙C整数不等比較結果
ival: 0, min: -2147483648, max: 2147483647, too big: 0, too small: 1
可能ということですどのように?
(私は実際にgetargs.c
ではCPython 2.7.3でこの問題/バグに見舞われました:。convertsimple
あなたはコードを見てみると、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 – TheZ
@Albert興味深いことに、ival:0、min:-2147483648、max:2147483647、too big:0、too small:0' –
printfの%iフォーマットはないと思います。おそらく%dが必要です。そして、printfのようなvarargs関数の引数を明示的にintにキャストするのは良い習慣です。 (この場合、(a> bの値はint型にデフォルト設定されているので)必要ありません。 – wildplasser