这个问题在这里已有答案:
我正在尝试使我的代码更具可读性,因此我定义了以下宏来缩短对嵌套结构中组件的访问。
#define _ENTRY(i) policy_data->entries[i]
#define _ENTRY(i,j) policy_data->entries[i].sub_entry[j]
为了尝试这个,我得到一个关于“_ENTRY”被重新定义的编译器警告。
我认为宏只是一种复杂的方法来替换C文件中某些模板定义的字符串。在编译之前由预处理器完成的作业。
那么为什么编译器会关心这个呢?如何在没有错误的情况下实现相同的功能?
使用像_ENTRY
这样的标识符是导致未定义行为的原因。
C11标准对identifiers说明了这一点:
7.1.3保留标识符
1每个标头声明或定义其关联子条款中列出的所有标识符,并可选地声明或定义其关联的未来库方向子条款和标识符中列出的标识符,这些标识符始终保留用于任何用途或用作文件范围标识符。
- 所有以下划线开头的标识符以及大写字母或另一个下划线始终保留用于任何用途。 ... 3如果程序删除(使用#undef)上面列出的第一个组中标识符的任何宏定义,则行为未定义。
因此,在某些实现中可能会删除整个宏。这进一步导致了可移植性问题。
C11标准在Annexure on Portability and Undefined behavior中陈述:
该程序删除名称以下划线和大写字母或另一个下划线开头的宏的定义