V2EX = way to explore
V2EX 是一个关于分享和探索的地方
Sign Up Now
For Existing Member  Sign In
p64381
V2EX  ›  问与答

请教 C 语言中, gcc 编译器 对未对其的访问是怎么处理的呢?

  •  
  •   p64381 · Feb 13, 2018 · 2754 views
    This topic created in 2999 days ago, the information mentioned may be changed or developed.

    平台为 x86 或者 路由器常见的 MIPS x86 gcc 7.3 MIPS gcc 7.5

    比如这个代码

    char buf[10];
    uint32_t *p = (uint32_t *) (buf+1); // p 指向没有 4 字节对其的地址。
    
    // 下面的各种操作也都是正常的 (至少运行起来是正常的)
    *p = 0x12345678;
    *p = *p + 1;
    

    这样没有对其的情况下会有什么影响呢? “对齐”操作是编译器工作还是 CPU 的工作呢? 会有多大效率差别呢?

    8 replies    2018-02-14 13:51:51 +08:00
    WordTian
        1
    WordTian  
       Feb 13, 2018 via Android
    内存数据对齐,和硬盘 4K 对齐起的作用类似啊。

    内存也是由很多个块组成的,没对齐的话,很多数据就会同时存在两个块中,就要从两个块中进行读取。

    效率的话,取决于你的数据类型,块大小,和 CPU 从内存中取数据的机制吧应该
    WordTian
        2
    WordTian  
       Feb 13, 2018 via Android
    有些嵌入式设备的 CPU 就没有从两个块中取数据再提取合并的机制,碰上这种情况应该就抓瞎了
    xwyam
        3
    xwyam  
       Feb 13, 2018 via Android
    我在 Cavium 的 MIPS 下遇到过问题的。还是建议声明一个 int 变量,用 memcpy 在变量和缓冲区之间复制数据,这样一般没有坑。
    wzxlovesy
        4
    wzxlovesy  
       Feb 14, 2018 via Android
    一般机器都是 32 位机器,所以一次操作 4 字节是有效的,注意大小头,注意越界就行
    changnet
        5
    changnet  
       Feb 14, 2018 via Android
    这个是分为两种情况的
    1. 编译器在编译的时候能识别,会自动帮你对齐,损失一些效率但不是很大
    2.cpu 指令支持不对齐数据读取,比如 x86 cpu,也只是影响一些效率
    3.cpu 不支持不对齐数据读取,程序应该是挂掉
    congeec
        6
    congeec  
       Feb 14, 2018 via iPhone
    编译器咋处理的我不清楚,得看汇编代码
    不过我确定栈已经破坏了,这程序吃枣药丸
    zwyc
        7
    zwyc  
       Feb 14, 2018 via Android
    楼主的示例中,代码就是要去访问一个非对齐的地址,编译器是不会去帮忙做对齐的。如果去做就是改变了原有的代码行为。编译器就是做了错误的优化。
    ironx
        8
    ironx  
       Feb 14, 2018 via Android
    @zwyc 正解。arm 不支持非对齐访问,会上报异常。
    About   ·   Help   ·   Advertise   ·   Blog   ·   API   ·   FAQ   ·   Solana   ·   2564 Online   Highest 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 49ms · UTC 07:47 · PVG 15:47 · LAX 00:47 · JFK 03:47
    ♥ Do have faith in what you're doing.