输入投射指针取消引用

时间:2016-01-13 18:59:06

标签: c pointers casting dereference

通过退役的工程师代码排序,我遇到了一个相当简单的宏,但我的C知识并不是很好。

#define mem32(addr) (*(unsigned long volatile *)(addr)) 
  1. 我是否正确地将其称为类型转换指针取消引用?
  2. 它会对 addr 进行类型转换,然后对其进行解除?或者相反?这有关系吗?
  3. 对于类型限定符和类型说明符,顺序是否重要?我假设(在此之前)类型限定符必须在类型说明符之前,但不一定是这种情况
  4. 语法问题。第二个*?
  5. 的目的是什么?

2 个答案:

答案 0 :(得分:1)

  
      
  1. 我是否正确地将其称为类型转换指针取消引用?
  2.   

是。

  
      
  1. 它类型转换为addr然后derefences它?或者相反?这有关系吗?
  2.   

*(unsigned long volatile *)(addr)是类型转换addr,然后取消引用它。

  
      
  1. 对于类型限定符和类型说明符,顺序是否重要?
  2.   

没有。订单无关紧要。 C11部分§6.7.2/ 2

  

[...]类型说明符可能以任何顺序出现   与其他声明说明符混合。 [...]

答案 1 :(得分:1)

演员(unsigned long volatile *)(addr)在解除引用之前发生。

不,只要在中没有混合其他运算符,单词unsignedlongvolatile的顺序与无关。 I. e。 volatile int*int volatile*是相同的,但int * volatile是不同的。

在高级别上,此宏的目的是获取任何指针,并从该内存地址读取前四个字节。

但是,如果传递给mem32的指针既不是指向longchar的指针,则会调用未定义的行为!这是由于严格的别名规则。较旧的编译器用于安全地生成此宏的预期代码,但现代编译器可能只是使用该宏来优化代码,如果它们证明类型不匹配。所以,不要在新代码中使用它。