Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/webpack/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
奇怪的C整数不等式比较结果_C_Arm - Fatal编程技术网

奇怪的C整数不等式比较结果

奇怪的C整数不等式比较结果,c,arm,C,Arm,这怎么可能 (实际上,我在getargs.c:convertsimple中遇到了CPython 2.7.3中的这个问题/错误。如果您查找代码,在案例“I”中,有一个检查ivalb)的值默认为int类型)@wildplasser:是的,printf有一种%i格式。它与%d.Oops相同。我的错。我认为is是前一个扩展的残余。根据C标准,将int转换为long而不保留符号是错误的。任何兼容的C实现都不能执行此操作。000000214748364700000000 80000000%16lx格式需要一

这怎么可能

(实际上,我在
getargs.c
convertsimple
中遇到了CPython 2.7.3中的这个问题/错误。如果您查找代码,在
案例“I”
中,有一个检查
ival
,它对我来说总是正确的。另请参阅。)


嗯,我现在测试了一些不同的编译器。为x86编译的GCC/Clang都返回预期值(太小:0)。为armv7编译时,意外的输出来自Xcode工具链中的叮当声


如果要复制:

这是确切的编译命令:
/Applications/Xcode.app/Contents/Developer/toolschains/xcodefault.xctoolschain/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上并执行它

如果有人对由此生成的汇编代码感兴趣:

ival: 0, min: -2147483648, max: 2147483647, too big: 0, too small: 1
这印的是什么

    .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
#包括
printf(“%016ld\n”,最大长度);
长l_int_min=(长)int_min;
printf(“%016lx\n”,l\u int\u min);
我想知道
INT\u MIN
是否被强制为
long
,而不进行符号扩展。这将使0小于结果值

编辑:好的,第一个
printf()
的结果是
0000002147483647
,这意味着
long
在该平台上是32位的,就像
int
一样。因此,将
int
转换为
long
实际上不会改变任何东西


我试图保留“这是一个编译器错误”作为最后手段,但这看起来像是一个编译器错误。

这是一个错误。C标准中没有空间容纳
太小
而不是0。下面是它的工作原理:

  • 由于
    INT\u MIN
    是一个
    INT
    ,因此在“常用算术转换”过程中,它会转换为
    long
    。这是因为
    long
    的秩高于
    int
    (两者都是有符号类型)。由于所有操作数至少具有
    int
    秩,因此不会发生升级。未调用任何未定义或实现指定的行为

  • 在转换过程中,
    INT_MIN
    的值被保留。由于它正在从
    int
    转换为
    long
    ,并且保证
    long
    至少具有
    int
    的范围,因此在转换过程中必须保留
    int\u MIN
    的值。未调用任何未定义或实现指定的行为。不允许进行模块转换,这些转换仅适用于无符号类型

  • 比较结果应为
    0

  • 对于标志延伸或其他类似的事情,没有回旋的余地。另外,由于对
    printf
    的调用是正确的,因此没有问题

    如果您可以在另一个系统上复制它,或者将它发送给其他可以复制它的人,那么您应该直接向您的工具链供应商报告错误

    尝试重现该错误:我无法在以下任何组合上重现该行为,所有这些组合都启用和禁用了优化:

    • GCC 4.0,PPC+PPC64
    • 通用条款4.2,PPC+PPC64
    • 通用条款4.3,x64
    • GCC 4.4,x64
    • 叮当声3.0,x64

    可能是演员的一个怪癖?是否可能是将INT_MIN转换为long并且未正确处理该标志?反之亦然?O。o@Albert有趣的是,我得到了
    ival:0,min:-2147483648,max:2147483647,太大:0,太小:0
    我认为printf没有%I格式。您可能需要%d。而且,将诸如printf之类的varargs函数的参数显式强制转换为int是一个好习惯。(在这种情况下,不需要,因为(a>b)的值默认为int类型)@wildplasser:是的,
    printf
    有一种
    %i
    格式。它与
    %d
    .Oops相同。我的错。我认为is是前一个扩展的残余。根据C标准,将
    int
    转换为
    long
    而不保留符号是错误的。任何兼容的C实现都不能执行此操作。
    0000002147483647
    00000000 80000000
    %16lx格式需要一个无符号长整型参数。l_int_min作为带符号的long传递。它的值是使用INT_MIN初始化的,INT_MIN在使用前经过符号扩展。是的,
    %16lx
    格式需要一个无符号的长字符。但是因为
    printf()
    并不是真正的类型安全,如果你传递一个有符号的long并用这种格式打印它,我希望它能打印出一个合理的结果。我也只能在ArchArmV7的Xcode(4.3.2)工具链中用-O0复制它。通过优化,我得到了预期的结果。看起来像个真正的虫子。我报告了。
        .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
    
    #include <limits.h>
    
    printf("%016ld\n", LONG_MAX);
    
    long l_int_min = (long)INT_MIN;
    printf("%016lx\n", l_int_min);