zoukankan      html  css  js  c++  java
  • char/unsigned char对比较结果的致命影响

    一、字符符号
    这个问题以前知道char类型有默认有符号和无符号的区分,但是这两种区分到底有什么区别,概念还是比较模糊的,直到今天因为字符符号搞了一个大乌龙,搞的版本无法启动,才算是有了一次刻骨铭心的认识。
    二、比较语句
    下面是比较的一个模型,gcc中,char类型在i386/MIPS体系结构默认是有符号的,而PowerPC/ARM是无符号的。现在看一个比较指令
    int foo(char cond)
    {
      return cond == 0xCC;
    }
    这个现在假设char传入的值为0xCC,此时这个函数返回值是多少呢?非常惊讶的是,返回值为0,事实上这是一个恒为0的函数,在fedora core上编译该文件
    [root@Harry falsealways]# cat falsealways.c
    int foo(char cond)
    {
        return cond == 0xcc;
    }
    [root@Harry falsealways]# gcc -c falsealways.c -Wall
    [root@Harry falsealways]# objdump -d falsealways.o

    falsealways.o:     file format elf32-i386


    Disassembly of section .text:

    00000000 <foo>:
       0:    55                       push   %ebp
       1:    89 e5                    mov    %esp,%ebp
       3:    83 ec 04                 sub    $0x4,%esp
       6:    8b 45 08                 mov    0x8(%ebp),%eax
       9:    88 45 fc                 mov    %al,-0x4(%ebp)
       c:    b8 00 00 00 00           mov    $0x0,%eax  这里返回值始终为0,也就是无论你传入什么值,这个函数都只会返回零,这个返回值在编译时就确定了
      11:    c9                       leave  
      12:    c3                       ret    
    [root@Harry falsealways]# gcc -v
    Using built-in specs.
    Target: i686-redhat-linux
    Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-languages=c,c++,objc,obj-c++,java,fortran,ada --enable-java-awt=gtk --disable-dssi --enable-plugin --with-java-home=/usr/lib/jvm/java-1.5.0-gcj-1.5.0.0/jre --enable-libgcj-multifile --enable-java-maintainer-mode --with-ecj-jar=/usr/share/java/eclipse-ecj.jar --disable-libjava-multilib --with-ppl --with-cloog --with-tune=generic --with-arch=i686 --build=i686-redhat-linux
    Thread model: posix
    gcc version 4.4.2 20091027 (Red Hat 4.4.2-7) (GCC) 
    三、gcc是怎么看这个问题的
    对于 
    cond == 0xCC;
    更为清楚的表达为
    (char)cond == 0x000000CC;
    也就是说,这个0xcc你看起来是一个字符常量,事实上他是一个整数常量,占用4个字节,所以char类型要向它看齐,从char拔高到int。

    1、假设传入的cond值为负数,在进行带符号扩展时,最高3byte全部补充为0xFF,即为0xFFFFFFFXX,由于高3bytes和常量0x000000CC的对应值不同,所以两个值肯定不同;
    2、假设cond的值为正值,那么它作为char的最高bit,也就是从右向左的第八bit为0,而常量0x000000cc的第八bit为1,所以也不可能相等。

    但是等一下,在4.1编译器中这里还会给一个警告,为什么这个坑爹的4.4即使加了Wall选项还是没有呢?
     
     
     
     
     
  • 相关阅读:
    TCP源码—连接建立
    TCP系列02—连接管理—1、三次握手与四次挥手
    TCP系列01—概述及协议头格式
    ubuntu软件管理apt与dpkg
    318. Maximum Product of Word Lengths
    317. Shortest Distance from All Buildings
    316. Remove Duplicate Letters
    315. Count of Smaller Numbers After Self
    314. Binary Tree Vertical Order Traversal
    313. Super Ugly Number
  • 原文地址:https://www.cnblogs.com/tsecer/p/10486095.html
Copyright © 2011-2022 走看看