为什么这个如果编译成无限循环?

J.D*_*Doe 1 c assembly arm

下面的C代码:

s32 load_string(char* string_new, char const* string_orign)
{
    StrEntry *entry = search_str_entry(string_orign);
    u8        buff_b[32];
    u16       buff_u[32];
    s32       read_size = 0;
    void     *str_file = 0;

    if (entry != 0){
        cmemclr(buff_b, 32);
        cmemclr(buff_u, 64);
        sprintf(&buff_b[0], "c:/data/%03d.str", entry->fid);
        c2w(&buff_u[0], &buff_b[0], 32);
        if (TryOpenFile(&str_file, buff_u, OPEN_MODE_READ) == 0){
            cmemclr(string_new, 256);
            TryReadFile(&read_size, str_file, entry->offset, string_new, entry->size);

            CloseFile(str_file);
            return (s32)entry->size;
        }
    }
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

这个函数的反汇编:

  003464ac <load_string>:
  3464ac:   e92d4010    push    {r4, lr}
  3464b0:   e1a00001    mov r0, r1
  3464b4:   ebffffda    bl  346424 <search_str_entry>
  3464b8:   e3500000    cmp r0, #0
  3464bc:   08bd8010    popeq   {r4, pc}
  3464c0:   eafffffe    b   3464c0 <load_string+0x14>
Run Code Online (Sandbox Code Playgroud)

我们可以看到if部分变成无限循环,为什么?

我使用-Os optimize选项来编译这段代码.gcc版本是

gcc版本8.1.0(devkitARM版本49).

编辑:

cmemclr是一个简单的内联函数:

static inline void cmemclr(void *buf, u32 size)
{
    u8 *dst = (u8*)buf;

    while(--size >= 0){
        dst[size] = 0;
    }
}
Run Code Online (Sandbox Code Playgroud)

Eri*_*hil 6

cmemclr是有缺陷的.根据问题的编辑,cmemclr是:

static inline void cmemclr(void *buf, u32 size)
{
    u8 *dst = (u8*)buf;

    while(--size >= 0){
        dst[size] = 0;
    }
}
Run Code Online (Sandbox Code Playgroud)

因为size类型u32(大概是无符号的--size >= 0)总是如此.代码进入无限循环.

问题编辑前的答案

一种可能性是您显示的汇编代码不完整,而当前显示的汇编代码b 3464c0将在以后解析为另一个地址.

假设程序集是正确的,并且不是一个等待进一步链接解析的不完整占位符,编译器已将if语句内的代码优化为无限循环,因为语句中存在未定义的行为(因此无限循环是允许的行为)或者因为语句中的某些内容执行无限循环.

由于您未提供if语句中使用的例程或宏的实现或规范,因此无法进一步诊断.