2014-05-22 25 views
5

我有两个C源代码文件;一个文件包含类似下面的声明:引用另一个C源文件中声明的volatile变量时,是否需要extern关键字?

volatile unsigned char flag=0; 

其他C文件包含如参考:

extern unsigned char flag; 

这是正确的,安全的,或当引用变量应volatile关键字重复?即

extern volatile unsigned char flag; 
+2

您使用的是C或C++编译器吗?看起来你不应该在这里使用'C++'标签。 –

+0

现在,如果您想知道C和C++之间的答案是否会有所不同,那很好。使用两个标签**并在您的问题中解释您关心两种语言**的方式。 –

+0

编译器只有* extern *声明,并生成代码来访问变量当然不知道它应该被视为易失性。链接器不会“修复”该代码,这不是它的工作。你不能忽略它。 –

回答

8

不,这是不正确的。

的相同的变量需要使用类型完全相同的所有声明和volatile是(不extern的)类型的一部分

检查extern声明一个好的做法是把它们放在一个头文件这也包含在定义存在的编译单元中。然后编译器会检查它们的正确性。

Notice what happens if you do that on this example

prog.c:2:22: error: conflicting type qualifiers for ‘flag’ 
extern unsigned char flag; 
        ^
prog.c:1:24: note: previous definition of ‘flag’ was here 
volatile unsigned char flag=0; 
+0

我特别避免将不应该应用于volatile变量的优化放到我的答案中,以避免看起来这样的处理得到保证。如果你想*那*行为,做一个指针并且抛弃'volatile'。但使用不兼容的定义是未定义的行为,并可能导致更糟糕的事情,不尊重波动。 –

4

C99标准一些引号(强调)

6.2.5/25型

任何类型到目前为止提到的是不合格的类型。每个不合格的 类型具有多个合格版本的类型,对应于const,volatile和 限制限定符中的一个,两个或全部三个的组合。 一个 类型的合格或不合格的版本是不同的类型

6.2.7/2“兼容型和复合型”

两种类型的具有兼容的类型,如果其类型是相同的。

...

是指同一对象或函数应具有 兼容所有类型的声明;否则,的行为是未定义的

如果你认为你的具体的例子了一会儿,怎么会是只看到下面的声明代码:

extern unsigned char flag; 

有什么想法,flag需要被视为volatile

此外,与您的问题无关,请记住volatile通常不足以处理通过多个线程访问(如果这是您的意图)。

+0

用于C代码的术语“一个定义规则”与C++中的相同吗? –

+1

@Ben:我不认为C标准文档使用该术语(而C++标准)。但是,我认为'一个定义'的概念也适用于C,即使它没有在标准文档中明确使用。 –

相关问题