You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Zynq Ultrascale+平台编译器优化导致循环提前退出问题咨询

编译器优化导致循环提前退出的原因分析

在Zynq Ultrascale+ ARM核心上使用aarch64-none-elf-g++开发时,遇到了编译器优化相关的异常:开启-O2优化后,代码中的循环会提前退出,而-O0优化级别下行为符合预期。

复现代码

#include <cstdint>
#include <string>
#include <vector>

class TestClass
{
private:
    std::vector<int> command_buffer;
public:
    TestClass() : command_buffer({}) {}
    void read_command();
};

void TestClass::read_command()
{
    printf("Before %lu\n", 67ul);

    size_t s = 42;
    while (true)
    {
        s = this->command_buffer.size();

        if (s > 0)
        {
            break;
        }
    }

    printf("Size %lu:\n", s);
}

int main()
{
    TestClass tester{ };
    tester.read_command();
}

预期与实际输出

  • 无优化(-O0)输出:

Before: 67
(程序无限循环,无后续输出)

  • -O2优化输出:

Before: 67
Size: 0

问题汇编代码

.LC0:
    .string "Before: %lu\n"
    .align  3
.LC1:
    .string "Size: %lu\n"
    .text
    .align  2
    .p2align 4,,11
    .global _ZN9TestClass12read_commandEv
    .type   _ZN9TestClass12read_commandEv, %function
_ZN9TestClass12read_commandEv:
.LFB2157:
    .cfi_startproc
    stp x29, x30, [sp, -32]!
    .cfi_def_cfa_offset 32
    .cfi_offset 29, -32
    .cfi_offset 30, -24
    adrp    x1, .LC0
    mov x29, sp
    str x19, [sp, 16]
    .cfi_offset 19, -16
    mov x19, x0
    add x0, x1, :lo12:.LC0
    mov x1, 67
    bl  printf
    ldp x2, x1, [x19]
    adrp    x0, .LC1
    ldr x19, [sp, 16]
    add x0, x0, :lo12:.LC1
    ldp x29, x30, [sp], 32
    .cfi_restore 30
    .cfi_restore 29
    .cfi_restore 19
    .cfi_def_cfa_offset 0
    sub x1, x1, x2
    asr x1, x1, 2
    b   printf
    .cfi_endproc

问题原因

这个问题的核心是编译器基于C++标准的"as-if"规则和未定义行为的优化:

  • 代码中的command_buffer是当前线程的私有变量,在read_command的循环体内,没有任何代码会修改该vector的大小,也没有同步机制(如volatile、原子操作、互斥锁)允许其他线程修改它。编译器在-O2优化时会判定:command_buffer.size()的返回值是恒定不变的,初始值为0。
  • 循环逻辑是"当size为0时持续循环",这属于无限循环且无任何可观测行为(既没有IO操作,也没有修改volatile变量或其他会影响外部环境的操作)。根据C++标准,这种无限循环属于未定义行为。
  • 对于未定义行为,编译器可以任意处理,这里它直接优化掉了整个循环逻辑,直接执行后续的printf语句,导致程序提前退出。
  • 而-O0级别下,编译器关闭了大部分优化,会严格按照代码的字面逻辑执行,每次循环都会重新读取vector的size,因此表现为无限循环,符合预期。

内容的提问来源于stack exchange,提问作者Matthew Dvorsky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 11:12:37