有没有办法在包含在同一文件中的不同文件中使用相同的#define 语句
Is there a way to have the same #define statement in different files that are included into the same file
所以,我的文件结构是这样的:
- 文件A
- 文件B
- 文件C
文件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_IMAGE
和 FILE_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++ 中,您还可以选择通过将宏更改为 [内联] 函数并将它们放在不同的命名空间中来解决名称冲突。这可能比给名称加上前缀更容易让每个用户适应新名称。
所以,我的文件结构是这样的:
- 文件A
- 文件B
- 文件C
文件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_IMAGE
和FILE_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++ 中,您还可以选择通过将宏更改为 [内联] 函数并将它们放在不同的命名空间中来解决名称冲突。这可能比给名称加上前缀更容易让每个用户适应新名称。