重新定义宏

时间:2019-03-14 11:07:55

标签: c macros compiler-warnings

我试图使代码更具可读性,所以我定义了以下宏以缩短对嵌套结构内组件的访问。

#define  _ENTRY(i)         policy_data->entries[i]                
#define  _ENTRY(i,j)       policy_data->entries[i].sub_entry[j] 

为此,我收到了有关重新定义“ _ENTRY”的编译器警告。

我认为宏只是一种替换C文件中某些模板定义的字符串的复杂方法。 预处理程序在编译之前完成的工作。

那为什么编译器会关心这个呢? 如何在没有错误的情况下实现相同的功能?

1 个答案:

答案 0 :(得分:4)

使用诸如_ENTRY之类的标识符本身就是未定义行为的原因。

C11标准针对identifiers声明了这一点:

  

7.1.3保留标识符

     

1每个标头声明或定义在其关联的子句中列出的所有标识符,并可选地声明或定义在其关联的未来库指示子句中列出的标识符和始终保留用于任何用途或用作文件范围标识符的标识符。 / p>      

-所有以下划线开头,大写字母或另一个下划线开头的标识符始终保留供任何使用。
  ...
  3如果程序删除了(使用#undef)上面列出的第一组中标识符的任何宏定义,则行为未定义

因此,在某些实现中可能会删除整个宏。这也进一步导致了可移植性问题。

C11标准在Annexure on Portability and Undefined behavior中声明:

  

程序删除名称以“。”开头的宏的定义。   下划线和大写字母或另一个下划线