有没有办法在包含在同一文件中的不同文件中使用相同的#define 语句

Is there a way to have the same #define statement in different files that are included into the same file

所以,我的文件结构是这样的:

文件A包括文件B和文件C

文件 B 有:

#define image(i, j,    w) (image[ ((i)*(w)) + (j) ])

并且 FileC 有:

#define image(i, j,    h) (image[ ((j)*(h)) + (i) ])

在编译时我得到:

warning: "image" redefined

note: this is the location of the previous definition ...

此警告是否意味着它更改了最初在编译时找到它的其他文件的定义?

有什么方法可以在维护这两个定义的同时避免此警告,并将它们的不同定义应用于各自的文件?

提前谢谢你:)

Does this warning mean it changes the definition of the other file where it found it initially when compiling ?

节目是ill-formed。该语言没有指定在这种情况下会发生什么。如果编译器接受 ill-formed 程序,那么您必须阅读编译器的文档以了解它们在这种情况下的作用。

请注意,该程序甚至可能无法与其他编译器一起编译。

Is there any way to avoid this warning while maintaining these two defines, and them applying their different definitions on their respective files?

从技术上讲,您可以像这样使用 hack 而无需触及 header:

#include "FileB"
#undef image
#include "FileC"

但一个好的解决方案 - 如果您可以修改 headers - 就是不使用宏。编辑 headers 以删除它们。请改用函数,并在不同的命名空间中声明它们,这样它们的名称就不会冲突。


一些经验法则:

  • 不要使用不必要的宏。函数和变量优于宏。
  • 如果您确实需要使用宏,请遵循仅使用大写字母作为宏名称的通用约定。重要的是要确保宏名称不与 non-macros 混合,因为宏不尊重名称空间和范围。
  • 如果您需要单个 header 中的宏,则在不再需要时立即取消定义,而不是将其泄漏到其他 header 中。
  • 不要使用没有名称空间的名称。这将导致名称冲突。宏不遵循 C++ 名称空间,但您可以改为在它们的名称前加上前缀。例如,您可以有 FILE_B_IMAGEFILE_C_IMAGE(或基于具体上下文的更具描述性的内容)。

They are not functionally equivalent, one can be seen as a row-wise iteration and the other a column-wise

这似乎是重命名函数(或宏,如果您出于某种原因无法替换它们)的一个很好的论据。调用一个 row_wise 和另一个 column_wise 或类似的东西。使用描述性名称!

Does this warning mean it changes the definition of the other file where it found it initially when compiling ?

对于 GCC(已标记),这意味着从重新定义点开始使用第二个处理的定义,不仅包括在同一文件中,而且包括在翻译单元后面出现宏标识符的任何地方一个(。以前的出现将使用以前的定义。

C 语言规范和 C++ 语言规范均未提供更通用的答案:除具有相同标记序列之外的重新定义违反了语言约束,因此包含此类非标记序列的程序的翻译行为和执行行为-匹配重定义未定义。

Is there any way to avoid this warning while maintaining these two defines, and them applying their different definitions on their respective files?

如果这些定义仅在各自的文件中使用,那么最简单的解决方案是将每个文件都放在 #undef image 末尾。这在 C 和 C++ 中都有效。

如果两者都打算公开供其他文件使用,那么您将遇到名称冲突,您将不得不以一种或另一种方式解决。例如,您可以为每个定义和所有用途添加一个区分前缀。仅在 C++ 中,您还可以选择通过将宏更改为 [内联] 函数并将它们放在不同的命名空间中来解决名称冲突。这可能比给名称加上前缀更容易让每个用户适应新名称。