首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >数组和类型的易失性的含义

数组和类型的易失性的含义
EN

Stack Overflow用户
提问于 2012-11-02 16:31:02
回答 2查看 263关注 0票数 6

各位,

考虑一下这段(令人讨厌的)代码:

代码语言:javascript
复制
volatile unsigned long a[1];  
unsigned long T; 

void main(void) 
{    
    a[0] = 0x6675636b;   /* first access of a */
    T = *a; 
    *(((char *)a) + 3) = 0x64; /* second access of a */
    T = *a;
}

...the问题:((char *)a)是易挥发的还是非易失性的?

这就引出了一个更大的问题:两个访问之间是否应该存在依赖关系?也就是说,人类的常识说有,但是C99标准说易挥发的东西不会别名非易失性的东西--所以如果((char *)a)是非易失性的,那么这两个访问就没有别名,也没有依赖性。

更准确地说,C99 6.7.3 (第5段)内容如下:

“如果试图通过使用具有非易失性限定类型的lvalue来引用使用易失性限定类型定义的对象,则该行为是未定义的。”

那么,当我们键入a时,是否适用易失性限定符?

EN

回答 2

Stack Overflow用户

发布于 2012-11-07 17:55:41

当有疑问时,运行一些代码:)我创建了一些类似的(稍微不那么可恶的)测试代码( msvs 2K10中的win32 C++应用程序)。

代码语言:javascript
复制
int _tmain(int argc, _TCHAR* argv[]) {
    int a = 0;
    volatile int b = 0;

    a = 1; //breakpoint 1
    b = 2; //breakpoint 2
    *(int *) &b  = 0; //breakpoint 3
    *(volatile int *) &b  = 0; //breakpoint 4

    return 0;
}

在编译以供发布时,允许我在2和4处断点,但不允许1和3断点。

我的结论是,类型决定了行为,1和3被优化。直觉支持这一点--否则编译器必须保留某种类型的列表,将所有内存位置列为易失性的,并检查每次访问(硬的、难看的),而不仅仅是将其与标识符的类型相关联(更容易、更直观)。

我还怀疑它是特定于编译器的(甚至在编译器中也可能是特定的),并且会在任何平台上进行测试,然后根据这种行为进行测试。

实际上,我只是尝试不依赖于这种行为:)

而且,我知道你是专门问数组的,但我怀疑这会有什么区别。您可以轻松地为数组编写类似的测试代码。

票数 1
EN

Stack Overflow用户

发布于 2012-11-02 16:42:33

就像你说的,它的“未定义”。这意味着恶魔会从你鼻子里冒出来。请尽量坚持“定义”的行为。volatile说明符将要求编译器不要优化该值,因为它是一个“重要”和临界值,如果由于不同的优化机制而更改,可能会导致问题。但这是它所能做的。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13199364

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档