今天我看到一段代码,其中一个特定的硬件地址被类型转换为
unsigned volatile long *
我知道它可以是volatile unsigned long
或unsigned long volatile
;这是定义volatile
的另一种方式还是代码中的错误?
我启用了警告,惊讶地发现没有警告。我使用的是GCC-4.7.0。
这只是另一种方式,没有语义上的区别。
C语言允许将类型说明符(int、unsigned、char、signed、void
等)、类型限定符(volatile、const
等)和存储类别说明符(static、extern
等)混合使用,且可以按任意顺序书写。这些东西都被称为“声明说明符”,其顺序不重要。
然而,在C标准的未来方向(C11 6.11)中指出:“在声明说明符中除了放置存储类别说明符之外的其他位置是一种废弃的特性。”
因此,您应该始终将存储类别说明符写在声明的开头。那些不这样做的代码不能保证在未来版本的C标准中编译通过。
我认为,由于这个原因,最好的编程风格是始终按照顺序书写说明符:[存储类别说明符] [类型限定符] [类型说明符]
,而且不要混合使用这3种类型。
因此,编写声明的最合适方式是:
volatile unsigned long *
或者,如果你想要不必要地冗长:
auto volatile unsigned long *
int volatile **x
、int * volatile *x
和int ** volatile x
模式中的不规则性。 - sh1unsigned volatile long *
本身不是一个易变对象,因此您建议的volatile unsigned long *
如果将volatile
错误地理解为存储类说明符,则有些误导。 - sh1volatile
不是这样的,因此它对于volatile
应该放置在序列中的位置没有影响。我的第一个示例和原始情况之间没有区别,这正是我的观点。如果标准规定了您的顺序,那么我们将有一个列表,其中包括volatile int **x
、int * volatile *x
和int ** volatile x
,以表示可以是volatile的三种不同事物。 - sh1