hrefspace

 找回密码
 立即注册
搜索
热搜: PHP PS 程序设计
查看: 799|回复: 9

volatile 可以用来修饰函数返回值吗

[复制链接]

494

主题

494

帖子

1506

积分

版主

Rank: 7Rank: 7Rank: 7

积分
1506
发表于 2024-3-19 00:16:04 | 显示全部楼层 |阅读模式
如题,可否举一个例子
回复

使用道具 举报

926

主题

1137

帖子

3586

积分

超级版主

Rank: 8Rank: 8

积分
3586

论坛头条论坛元老谋士数据帝优秀版主超级版主见习版主论坛版主

发表于 2024-3-19 00:16:14 | 显示全部楼层
such as
  1. volatile int volatileFun(void)
复制代码
回复

使用道具 举报

8

主题

204

帖子

44

积分

新手上路

Rank: 1

积分
44
发表于 2024-3-19 00:16:42 | 显示全部楼层
百度了一下,“volatile的变量是说这变量可能会被意想不到地改变”  我个人理解是对它的访问不做优化,对内存变量才有效,应该是编译器级别的约定(又如static 的变量会被解释成全局变量)。
函数的返回值在eax中,将忽略volatile。

小例:均启用/Ox优化
  1. #include <stdio.h>volatile int myfun(int n){    n=n+2;        return rand(n);}void main(){    volatile  int i=10;    //int i=10;    int a,b,c;    a=i;    b=i;    c=i;    printf("i=%d\n",a);    printf("i=%d\n",myfun(4));}
复制代码
片段:
  1. mov         DWORD PTR _i$[esp+4], 10  //imov         eax, DWORD PTR _i\$[esp+4] //amov         ecx, DWORD PTR _i\$[esp+4] //bmov         edx, DWORD PTR _i\$[esp+4] //c
复制代码
四次访存,未优化。
若改为 int i=10;则有
  a=i;
    b=i;
    c=i;
因未实际使用,已全被忽略。


以上对于函数返回值加与不加无影响,均为
push          eax
push         OFFSET    \$SG2233
call         _printf

总之,volatile 针对存变量,每次访存的话就不一定保存数据一致性了,且volatile  会影响全局优化。
有误之处请指正,也是才接触,似乎面试中常考,解释的也很玄。
回复

使用道具 举报

0

主题

167

帖子

10

积分

新手上路

Rank: 1

积分
10
发表于 2024-3-19 00:17:15 | 显示全部楼层
我也Google了下,结论是:volatile 可以用来修饰函数返回值。
volatile的本意是“易变的” 由于访问寄存器的速度要快过RAM,所以编译器一般都会作减少存取外部RAM的优化。


在linux的source code(linux/mm/memory.c)中有这样两句:
  1. volatile void do_exit(long code);static inline volatile void oom(void){    printk("out of memory\n\r");    do_exit(SIGSEGV);}
复制代码
volatile修饰函数是为了线程安全的考虑。

volatile 函数 是特指存在于volatile memory当中的函数吧,函数指针也是随时会变化的。

限定词volatile告诉编译器“不知道何时会改变”,防止编译器依据变量的稳定性作任何优化。当读在代码控制之外的某个值时,例如读一块通信硬件中的寄存器,将使用这个关键字。无论何时需要volatile变量的值,都能读到,即使在该行之前刚刚读过。

“在代码的控制之外”的某个存储空间的一个特殊例子是在多线程程序中。如果正在观察被另一个线程或进程修改的特殊标识符,这个标识符应该是volatile的,所以编译器不会认为它能够对标识符的多次读入进行优化。

注意当编译器不进行优化时,volatile可能不起作用,但是当开始优化代码时(当编译器开始寻找冗余的读入时),可以防止出现重大错误。

volatile的语法与const一样,但volatile的意思是“在编译器认识的范围外,这个数据可以改变”。就像建立const对象一样,程序员也可以建立volatile对象,甚至可以建立const volatile对象,这个对象不能被客户程序员改变,但可通过外部的代理程序改变。
回复

使用道具 举报

0

主题

171

帖子

2

积分

新手上路

Rank: 1

积分
2
发表于 2024-3-19 00:17:40 | 显示全部楼层
有人写了这样的测试例子:
  1. volatile int volatileFun(void){    printf("\n In volatileFun");    return 0;}
复制代码
我想其初衷就是防止该函数被优化掉了吧.
不知道编译器会对该函数具体作何种优化
回复

使用道具 举报

2

主题

174

帖子

41

积分

新手上路

Rank: 1

积分
41
发表于 2024-3-19 00:18:18 | 显示全部楼层
4# gxqcn
static inline volatile void oom(void)
这个太强悍了,

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

0

主题

184

帖子

14

积分

新手上路

Rank: 1

积分
14
发表于 2024-3-19 00:19:06 | 显示全部楼层
很想看看 linux/mm/memory.c,但没下载到。
就是想了解下用 volatile 修饰函数返回值的目的:真是声明该函数指针可能被更改吗?
回复

使用道具 举报

0

主题

170

帖子

2

积分

新手上路

Rank: 1

积分
2
发表于 2024-3-19 00:19:27 | 显示全部楼层
7# gxqcn
是不是 允许被线程更改
回复

使用道具 举报

0

主题

176

帖子

2

积分

新手上路

Rank: 1

积分
2
发表于 2024-3-19 00:20:05 | 显示全部楼层
volatile 修饰的目的是防止编译器优化,通知它是个可变的变量,主要来自其它线程的修改。
但用它来修饰 函数,我还没用过。
回复

使用道具 举报

0

主题

179

帖子

2

积分

新手上路

Rank: 1

积分
2
发表于 2024-3-19 00:20:26 | 显示全部楼层
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|手机版|小黑屋|hrefspace

GMT+8, 2024-5-3 04:34 , Processed in 0.071710 second(s), 23 queries .

Powered by hrefspace X3.4 Licensed

Copyright © 2022, hrefspace.

快速回复 返回顶部 返回列表