还在苦苦敲代码开发APP?你out啦! 试试积木搭建APP吧~

c/c++ volatile和mutable关键字

来源:转载     2017-03-08 13:50:35    人气:     我有话说( 0 人参与)

1 volatile关键字:一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。例如:假设编译

1、volatile关键字:

一个定义为volatile的变量是说这变量可能会被意想不到地改变,这样,编译器就不会去假设这个变量的值了。例如:假设编译器发现,程序在几条语句中两次使用了某个变量的值,则编译器可能不是让程序查找这个值两次,而是将这个值缓存到寄存器中。这种优化假设变量的值在这两次使用之间不会变化。如果不将变量声明为volatile,则编译器将进行这种优化;将变量声明为volatile,相当于告诉编译器,不要进行这种优化。精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值(From Memory),而不是使用保存在寄存器里的备份。

下面是volatile变量的几个例子:
1) 并行设备的硬件寄存器(如:状态寄存器)
2) 一个中断服务子程序中会访问到的非自动变量(Non-automatic variables)
3) 多线程应用中被几个任务共享的变量

问题:
1)一个参数既可以是const还可以是volatile吗?解释为什么。
2); 一个指针可以是volatile 吗?解释为什么。
3); 下面的函数有什么错误:

int square(volatile int *ptr)
{
    return *ptr * *ptr;
}

下面是答案:

1)是的。一个例子是只读的状态寄存器。它是volatile因为它可能被意想不到地改变。它是const因为程序不应该试图去修改它。

2)是的。一个例子是当一个中服务子程序修该一个指向一个buffer的指针时。

3) 这段代码有点变态。这段代码的目的是用来返指针*ptr指向值的平方,但是,由于*ptr指向一个volatile型参数,编译器将产生类似下面的代码:

int square(volatile int *ptr)
{
    int a,b;
    a = *ptr;
    b = *ptr;
    return a * b;
}

由于*ptr的值可能被意想不到地该变,因此a和b可能是不同的。结果,这段代码可能返不是你所期望的平方值!正确的代码如下:

long square(volatile int *ptr)
{
    int a;
    a = *ptr;
    return a * a;
}


2、mutable关键字:

即使结构或类变量为const,其某个成员也可以被修改。如:

struct data
{
    char name[30];
    mutable int accesses;
};
const data veep = {"hello", 0};
strcpy(veep.name, "hel"); //not allowed
veep.accessess++; //allowed

veep的const限定符进制程序修改veep的成员,但access成员的mutable说明符使得access不受这种限制。

volatile mutable

本文源自互联网,采用知识共享署名-非商业性使用 4.0 国际许可协议进行许可,
版权归原作者,如有问题请联系service@tsingfun.com (编辑:admin)
分享到: