(在我开始之前:我知道关于这个主题存在现有 问题,但我没有找到答案为什么这是一个问题。我经常这样做,并想知道我是否正在制造潜在的问题。)
我很好奇为什么在函数调用中丢弃 volatile 限定符会引起编译器警告。
情况如下:
volatile uint8_t thingy;
void awesome_function(uint8_t *arg);
awesome_function(&thingy); << warning
现在,我的理解是,volatile
限定符将变量标记为可能以编译器无法控制的方式发生变化的变量。某些优化(最重要的是,根据我的经验,删除“未使用”变量)因此被禁用。
但是,如果我将变量标记为volatile
,我会担心在此范围内阻止优化。如果我将变量传递给函数,我通常很乐意在该函数中应用标准优化。*
即使编译器想要从函数中删除变量(我通常试图避免的优化),情况也是如此,因为即使这样做,它也不影响我在这个范围内使用它;函数本身的(结果)是我感兴趣的序列点(和左值)。
那么,为什么丢弃与函数调用有关的限定符会发出警告,因为它不会在当前范围内启用重新排序?这是因为在被调用函数的范围内可能会重新排序,而变量不允许这样做volatile
?如果是这样,为什么这是当前范围的问题?
(* 这通常是因为这样的调用用于启动异步操作,最终将在传递给函数的指针上进行操作。该函数可以对指针做任何它喜欢的事情,只要它最终按要求更新它。volatile
限定符就在那里提醒编译器局部变量将异步更改。)