在 C/C++ 中,是否有类似于 #ifndef 的 typedef 指令?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/6772802/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-28 20:39:30  来源:igfitidea点击:

In C/C++, is there a directive similar to #ifndef for typedefs?

c++c

提问by Zach Rattner

If I want to define a value only if it is not defined, I do something like this :

如果我只想定义一个未定义的值,我会这样做:

#ifndef THING
#define THING OTHER_THING
#endif

What if THINGis a typedef'd identifier, and not defined? I would like to do something like this:

如果THINGtypedef'd 标识符,但未定义怎么办?我想做这样的事情:

#ifntypedef thing_type
typedef uint32_t thing_type
#endif

The issue arose because I wanted to check to see if an external library has already defined the booleantype, but I'd be open to hearing a more general solution.

出现问题是因为我想检查外部库是否已经定义了boolean类型,但我愿意听取更通用的解决方案。

采纳答案by iammilind

No there is no such facility in C++ at preprocessing stage. At the max can do is

不,在预处理阶段,C++ 中没有这样的设施。在最大可以做的是

#ifndef thing_type
#define thing_type uint32_t 
#endif

Though this is not a good coding practice and I don't suggest it.

虽然这不是一个好的编码习惯,我不建议这样做。

回答by David Rodríguez - dribeas

There is no such thing in the language, nor is it needed. Within a single project you should not have the same typedef alias referring to different types ever, as that is a violation of the ODR, and if you are going to create the same alias for the same type then just do it. The language allows you to perform the same typedef as many times as you wish and will usually catch that particular ODR (within the same translation unit):

语言中没有这样的东西,也不需要。在单个项目中,您不应该使用相同的 typedef 别名来引用不同的类型,因为这违反了 ODR,如果您要为相同的类型创建相同的别名,那么就这样做。该语言允许您根据需要多次执行相同的 typedef,并且通常会捕获该特定 ODR(在同一翻译单元内):

typedef int myint;
typedef int myint;       // OK: myint is still an alias to int
//typedef double myint;  // Error: myint already defined as alias to int

If what you are intending to do is implementing a piece of functionality for different types by using a typedef to determine which to use, then you should be looking at templates rather than typedefs.

如果您打算做的是通过使用 typedef 来确定要使用的类型来为不同类型实现一个功能,那么您应该查看模板而不是 typedef。

回答by Alok Save

C++ does not provide any mechanism for code to test presence of typedef, the best you can have is something like this:

C++ 没有为代码提供任何机制来测试 的存在typedef,你可以拥有的最好的东西是这样的:

#ifndef THING_TYPE_DEFINED
#define THING_TYPE_DEFINED
typedef uint32_t thing_type 
#endif

EDIT:
As @David, is correct in his comment, this answers the how?part but importantly misses the why?It can be done in the way above, If you want to do it et all, but important it you probably don't need to do it anyways, @David's answer & comment explains the details, and I think that answers the question correctly.

编辑:
作为@David,在他的评论中是正确的,这回答了如何?部分但重要的是错过了为什么?可以通过上述方式完成,如果您想全部完成,但重要的是您可能无论如何都不需要这样做,@David 的回答和评论解释了详细信息,我认为这正确地回答了问题。

回答by Mike Seymour

Preprocessor directives (like #define) are crude text replacement tools, which know nothing about the programming language, so they can't act on any language-level definitions.

预处理器指令(如#define)是粗略的文本替换工具,它们对编程语言一无所知,因此它们不能对任何语言级别的定义起作用。

There are two approaches to making sure a type is only defined once:

有两种方法可以确保一个类型只定义一次:

  • Structure the code so that each definition has its place, and there's no need for multiple definitions
  • #definea preprocessor macro alongside the type, and use #ifndefto check for the macro definition before defining the type.
  • 构建代码,让每个定义都有自己的位置,并且不需要多个定义
  • #define类型旁边的预处理器宏,#ifndef用于在定义类型之前检查宏定义。

The first option will generally lead to more maintainable code. The second could cause subtle bugs, if you accidentally end up with different definitions of the type within one program.

第一个选项通常会导致更易于维护的代码。如果您不小心在一个程序中使用了不同的类型定义,则第二个可能会导致细微的错误。

回答by B?ови?

As other have already said, there are no such thing, but if you try to create an alias to different type, you'll get a compilation error :

正如其他人已经说过的那样,没有这样的事情,但是如果您尝试为不同类型创建别名,则会出现编译错误:

typedef int myInt;
typedef int myInt;    // ok, same alias
typedef float myInt;  // error

However, there is a thing called ctagfor finding where a typedef is defined.

但是,有一种叫做ctag的东西可以用来查找定义 typedef 的位置。

回答by mondaugen

This might not directly answer the question, but serve as a possible solution to your problem.

这可能不会直接回答问题,但可以作为您问题的可能解决方案。

Why not try something like this?

为什么不尝试这样的事情呢?

#define DEFAULT_TYPE int // just for argument's sake
#ifndef MY_COOL_TYPE
     #define MY_COOL_TYPE DEFAULT_TYPE
#endif
typedef MY_COOL_TYPE My_Cool_Datatype_t;

Then if you want to customize the type, you can either define MY_COOL_TYPE somewhere above this (like in a "configure" header that is included at the top of this header) or pass it as a command line argument when compiling (as far as I know you can do this with GCC and LLVM, maybe others, too).

然后,如果您想自定义类型,您可以在此之上的某处定义 MY_COOL_TYPE(例如在包含在此标题顶部的“配置”标题中)或在编译时将其作为命令行参数传递(就我而言知道你可以用 GCC 和 LLVM 来做到这一点,也许其他人也可以)。

回答by Swift - Friday Pie

The problem is actually real PITA, because some APIs or SDKs redefine commonly used things. I had issue that header files for a map processing software (GIS) were redefining TRUE and FALSE (generally used by windows SDK)keywords to integer literals instead of true and false keywords ( obviously, that can break SOMETHING). And yes, famous joke "#define true false" is relevant.

问题其实是真正的 PITA,因为一些 API 或者 SDK 重新定义了常用的东西。我有一个问题,地图处理软件 (GIS) 的头文件将 TRUE 和 FALSE(通常由 Windows SDK 使用)关键字重新定义为整数文字而不是 true 和 false 关键字(显然,这可能会破坏某些东西)。是的,著名的笑话“#define true false”是相关的。

define would never feel a typedef or constant declared in C\C++ code because preprocessor doesn't analyze code, it only scans for # statements. And it modifies code prior to giving it to syntax analyzer. SO, in general, it's not possible.

定义永远不会感觉到在 C\C++ 代码中声明的 typedef 或常量,因为预处理器不分析代码,它只扫描 # 语句。它会在将代码提供给语法分析器之前修改代码。所以,一般来说,这是不可能的。

https://msdn.microsoft.com/en-us/library/5xkf423c.aspx?f=255&MSPPError=-2147217396That one isn't portable so far, though there were known request to implement it in GCC. I think, it also counts as "extension" in MSVC. It's a compiler statement, not a preprocessor statement, so it will not "feel" defined macros, it would detect only typedefs outside of function body. "full type" there means that it will react on full definition, ignoring statements like "class SomeClass;". Use it at own risk.

https://msdn.microsoft.com/en-us/library/5xkf423c.aspx?f=255&MSPPError=-2147217396到目前为止,那个是不可移植的,尽管有已知的要求在 GCC 中实现它。我认为,它在 MSVC 中也算作“扩展”。这是一个编译器语句,而不是一个预处理器语句,所以它不会“感觉”定义的宏,它只会检测函数体之外的 typedef。“完整类型”意味着它将对完整定义做出反应,忽略诸如“class SomeClass;”之类的语句。使用它的风险自负。

Edit: apparently it also supported on MacOS now and by Intel comiler with -fms-dialect flag (AIX\Linux?)

编辑:显然它现在也支持 MacOS,英特尔编译器带有 -fms-dialect 标志(AIX\Linux?)

回答by SeanRamey

No there is nothing like what you wanted. I have had your same problem with libraries that include their owntypedefsfor things like bool. It gets to be a problem when they just don't care about what you use for boolor if any other libs might be doing the same thing!!

不,没有什么像你想要的。我在库中遇到了同样的问题,这些库包括它们自己typedefs的诸如bool. 当他们不关心您的用途bool或者是否有任何其他库可能在做同样的事情时,这就会成为一个问题!

So here's what I do. I edit the header file for the libs that do such things and find the typedef booland add some code like this:

所以这就是我要做的。我编辑了做这些事情的库的头文件,找到typedef bool并添加了一些这样的代码:

#ifdef USE_LIBNAME_BOOL
typedef unsigned char bool; // This is the lib's bool implementation
#else
#include <stdbool.h>
#endif

Notice that I included if I didn't want to use the libs' own bool typdef. This means that you need C99 support or later.

请注意,如果我不想使用库自己的bool typdef. 这意味着您需要 C99 或更高版本的支持。

回答by Zach Rattner

The solution I ended up using was including stdbool.h. I know this doesn't solve the question of how to check if a typedef is already defined, but it does let me ensure that the boolean type is defined.

我最终使用的解决方案是包含 stdbool.h。我知道这并不能解决如何检查 typedef 是否已定义的问题,但它确实让我确保定义了布尔类型。

回答by Tim

As mentioned before this is not included in the C++ standard, but you might be able to use autotools to get the same functionality.

如前所述,这不包含在 C++ 标准中,但您可以使用 autotools 来获得相同的功能。

You could use the ac_cxx_boolmacro to make sure bool is defined (or different routines for different datatypes).

您可以使用ac_cxx_bool宏来确保定义了 bool(或不同数据类型的不同例程)。