gpt4 book ai didi

c - 'while' 循环优化太多 - 为什么 nop() 会修复它?

转载 作者:太空狗 更新时间:2023-10-29 16:12:27 26 4
gpt4 key购买 nike

我想弄清楚为什么在对以下代码进行编译器优化后停止工作:

bool send_atcmd(char* atcmd, char* expected_response, unsigned int timeout)
{
volatile char* buf = uart_get_rx_buf(UART_MODEM);
bool response_match = false;
if (modem_powered_on)
{
__delay_cycles((unsigned long)500 * DELAY_MS);
uart_clear_rx_buf(UART_MODEM);
uart_puts(UART_MODEM, atcmd);
uart_putc(UART_MODEM, '\r');
timer_ms = 0;
while (!response_match && timer_ms <= timeout)
{
//__nop();
if (strstr(buf, expected_response) != NULL)
response_match = true;
}
uart_clear_rx_buf(UART_MODEM);
}
return response_match;
}

代码是用msp430-gcc编译的,buf指向modem运行的uart口的接收缓冲区。一切正常,直到没有优化 (-O0),但是当在 while 循环上打开优化时,timer_ms <= timeout 结束。条件为假,strstr(buf, expected_response)永远不会返回 !NULL。这是因为buf的内容好像没有更新。

但是,任何放在前面的东西 if (strstr(buf, expected_response) != NULL)在 while 循环中,例如取消注释 nop() 会使代码正常工作。

buf在 ISR 中更新。

为什么连 __nop() 都有帮助?

最佳答案

向 strstr 提供 volatile char * 会导致未定义的行为。

C99 Annex J.2(这是未定义行为的事物列表)

An attempt is made to refer to an object defined with a volatile-qualified type through use of an lvalue with non-volatile-qualified type (6.7.3)

这是有道理的,因为字符可能会在 strstr 操作期间更新,这可能会造成严重破坏。

一个建议的解决方法是使用锁或其他机制来确保字符不会被更新,然后将字符复制到非 volatile 缓冲区,然后将该缓冲区传递给 strstr .

或者,如果有一个函数可供您安全地从 uart 读取到非 volatile 存储区域,那也行。

Link to related SO thread

关于c - 'while' 循环优化太多 - 为什么 nop() 会修复它?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23709231/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com