c - 在 IAR MSP430 编译器中将优化设置为高时会发生指令的疯狂执行

标签 c compiler-optimization

请引用我下面的代码。当 IAR MSP430 编译器中的优化设置为高时,我遇到以下问题。当优化程度较低时,代码工作正常。

问题:如果 (B) 处的条件语句返回 false,则执行语句 (A) 而不是语句 (C)。


int16_t cpu_flash_read_setting (void * setting, const uint8_t offset, const uint8_t num_of_bytes)
{
    int16_t returnable_status = PASS;
    uint16_t flash_copy_one_address =  FLASH_INFO_SEG_C_ADDR + offset;
    uint16_t flash_copy_two_address =  FLASH_INFO_SEG_D_ADDR + offset;
    if (0U == (num_of_bytes % sizeof(uint16_t))) 
    {
        uint16_t *setting_copy_one = (uint16_t *) flash_copy_one_address;
        uint16_t *setting_copy_two = (uint16_t *) flash_copy_two_address;  
        if (*setting_copy_one == *setting_copy_two)
        {
            setting = setting_copy_one;       
        }
        else
        {
(A)         returnable_status = FAIL;         
        }
    }
    else if (0U == (num_of_bytes % sizeof(uint8_t))) 
    {
        uint8_t *setting_copy_one = (uint8_t *) flash_copy_one_address;
        uint8_t *setting_copy_two = (uint8_t *) flash_copy_two_address;  
(B)     if (*setting_copy_one == *setting_copy_two)
        {
            setting = setting_copy_one;       
        }
        else
        {
(C)        returnable_status = FAIL;         
        }      
    }
    else
    {
        /* No Action */
    }
    return returnable_status;    
}

最佳答案

我觉得这很合理。当您将优化调高时,编译器可以而且通常会疯狂地重新排序语句。除了它们的类型之外,您的两个主要子句是相同的 - 因此编译器合并执行路径并让它们仅在实际重要的地方有所不同是完全合理的。

只有当实际观察到的效果与预期不同时,这才是问题。

在任何情况下,优化代码总是很难用调试器跟踪,正是因为重新排序的影响。

顺便说一句,如果您的代码与实际硬件通信,您可能希望将 flash_copy_*_address 变量声明为 volatile。这是对编译器的一个提示,即它们指向的内存不一定以正常方式运行,并迫使其在优化方面更加保守。

关于c - 在 IAR MSP430 编译器中将优化设置为高时会发生指令的疯狂执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6200340/

相关文章:

c - 时钟时间和墙上时间有什么区别?

c++ - 是否可以在保持 RTTI 启用的情况下从可执行文件中删除类型名称?

c++ - 为什么这个未使用的变量没有被优化掉?

c++ - 除非使用 cout,否则代码不会执行

c - 有没有办法控制宏扩展顺序

c - 平台设备驱动的Major编号是怎么分配的?

将位域转换为字节数组

c++ - 最大subarray_problem理解

c++ - 具有 void 类型分支的三元运算符

c++ - 生命周期 dse 的 gcc 优化诊断