15

我遇到了一些C代码,其中作者到处使用以下成语:

typedef __int32 FOO_INT32;
#define FOO_INT32 FOO_INT32

这样做有什么意义?typedef 还不够吗?对于一些不稳定的C编译器来说,这是一种解决方法吗?

4

4 回答 4

29

使用该#define指令,您将能够使用以下代码测试 typedef 是否已在代码中的其他位置完成:

#ifdef FOO_INT32
FOO_INT32 myfoo;
#else
int myfoo;
#endif
于 2009-03-11T22:16:02.777 回答
3

这是一种有时在标题中完成的做法。#define 允许对 typedef 的存在进行编译时测试。这允许如下代码:

#ifdef FOO_INT32
FOO_INT32 myfoo;
#else
int myfoo;
#endif

或者作为一个真正的守卫#define,类似于头文件守卫。

#ifndef FOO_INT32
typedef int FOO_INT32
#define FOO_INT32 FOO_INT32
#endif

这不一定是一个好的做法,但它有它的用途,尤其是当您有一些使用其他库定义的类型的头文件时,但您想为根本不使用这些库的情况提供自己的替代品。

于 2009-03-12T14:07:37.323 回答
2

另一个原因是标准可能要求定义是宏。

来自 glibc 的片段netinet/in.h

/* Standard well-defined IP protocols.  */
enum
  {
    IPPROTO_IP = 0,    /* Dummy protocol for TCP.  */
#define IPPROTO_IP      IPPROTO_IP
    IPPROTO_ICMP = 1,      /* Internet Control Message Protocol.  */
#define IPPROTO_ICMP        IPPROTO_ICMP
    IPPROTO_IGMP = 2,      /* Internet Group Management Protocol. */
#define IPPROTO_IGMP        IPPROTO_IGMP

这里枚举符号也按照相关 POSIX 规范的要求导出为宏,引用:

标头应定义以下宏,用作 getsockopt() 和 setsockopt() 的 level 参数的值:

IPPROTO_IP

Internet protocol.

IPPROTO_IPV6

Internet Protocol Version 6.

...

于 2017-05-13T22:15:59.853 回答
1

这种模式对于微处理器中寄存器的特征检测也很有用,就像在这个问题中一样。比如可能有两个类似的头文件,一个定义了一个定时器,一个定义了2个:

cheapprocessor.h

#define TMR1 TMR1
extern volatile int TMR1;

expensiveprocessor.h

#define TMR1 TMR1
extern volatile int TMR1;
#define TMR2 TMR2
extern volatile int TMR2;

这意味着在您的主代码中,当您包含一个processor.h委托给目标的适当标头的泛型时,您可以检测功能:

#include <processor.h>

#ifdef TMR2
    x = TMR2;
#else
    x = 0;  // no timer, probably because we're on the cheaper model
#endif
于 2016-11-14T13:10:52.827 回答