如果在下面的函数中传递了一个volatile变量...
此函数是否总是返回一个平方值,我的意思是有时可以更改值,因为声明了一个volatile变量。
基本上,我想说的是传递的变量是volatile。希望,我很清楚。但是,如果我通过引用传递将改变整个场景......我是对的吗?
volatile int a;
int main()
{
function(a);
return 1;
}
int function b(int a)
{
int x=a;
int y=a;
return x*y;
}
答案 0 :(得分:7)
volatile
限定符告诉编译器变量可能会更改而不是将更改。它无论如何都不能自发地改变;某些东西必须导致它改变 - 即使这个原因在代码外部。
在这种情况下代码是错误的(或者至少没有以你想要的方式举例说明volatile
的影响)因为传递给function()
的参数是而不是宣布挥发性。它与全局变量具有相同名称的事实可能令人困惑,但通过将全局变量a
分配给函数参数a
,您可以立即将其与波动率分离。
如果代码被修改(并且有效且可编译),那么:
volatile int a;
int function( void )
{
int x=a;
int y=a;
return x*y;
}
int main()
{
function();
return 1;
}
然后volatile
的效果就是编译器将明确指定x
和y
而不应用任何可能的优化。如果没有限定符,编译器可能会(在启用优化时)将function()
简化为:
int function( void )
{
return a * a ;
}
甚至可以在线整个功能。此外,由于函数的返回值未分配给任何东西,编译器可能会将整个代码优化为
int main()
{
return 1;
}
如果a
是易变的,那么在调用x
时,y
和function()
的分配必须。
volatile
的目的是向编译器指示变量可能在编译器生成的代码之外发生变化(而不是将更改)。当变量引用硬件寄存器或在线程,进程甚至处理器内的处理器或内核之间共享的内存时,它通常用于确保正确的行为。它还可以用于防止“优化”所需的代码(例如,空忙等待循环计数器)。在您的示例中(或者更确切地说是我的修订版),a
不引用任何此类实体,因此代码将按预期运行,但可能效率低于其他情况。
答案 1 :(得分:5)
全局范围volatile int a
和函数范围int a
参数之间没有关系。它们完全独立,对函数内部a
的任何引用都引用int a
参数。在这个程序中根本没有使用volatile int a
。
如果您将volatile int a
作为参数传递给函数,那么它就没有区别,因为a
的值将被读取一次并复制到函数的{{1} }参数,它本身不是a
。
答案 2 :(得分:5)
除非发生整数溢出,否则它总是返回一个正方形,在这种情况下,行为是未定义的。 volatile
完全不相关(我称之为红鲱鱼)但是因为全局volatile
变量a
甚至不在范围内读取其他a
。函数参数a
会影响全局变量,并且由于它具有自动存储持续时间并且从不采用其地址,因此它完全不受任何外部修改的影响。
当然,仍有很多方法可以通过调用未定义的行为来破坏程序状态,并发现返回值不是正方形。 UB很有趣......