What is the point of saying “#define FOO FOO” in C?

微笑、不失礼 提交于 2020-01-24 20:45:06

问题


I came across some C code where the author uses the following idiom all over the place:

typedef __int32 FOO_INT32;
#define FOO_INT32 FOO_INT32

What is the point of doing this? Shouldn't the typedef be enough? It is a workaround for some wonky C compilers out there?


回答1:


With the #define instruction, you'll then be able to test if the typedef has been done somewhere else in the code using :

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



回答2:


It's a practice that's sometimes done in headers. The #define allows for compile-time testing of the existence of the typedef. This allows code like:

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

or as a true guard #define, similar to header file guards.

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

It's not necessarily a good practice, but it has its uses, especially when you have some headers which use types defined by other libraries, but you want to provide your own substitutes for cases when you're not using those libraries at all.




回答3:


Another reason is that a standard might require definitions to be macros.

Snippet from 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

Here enum symbols are also exported as macros as required by the relevant POSIX spec, quoting:

The header shall define the following macros for use as values of the level argument of getsockopt() and setsockopt():

IPPROTO_IP

Internet protocol.

IPPROTO_IPV6

Internet Protocol Version 6.

...




回答4:


This pattern is also useful for feature-detection of registers in microprocessors, as in this question. For instance, there may be two similar header files, one of which defines one timer, and one that defines 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;

Which means in your main code, when you include a generic processor.h that delegates to the appropriate header for the target, you can detect features:

#include <processor.h>

#ifdef TMR2
    x = TMR2;
#else
    x = 0;  // no timer, probably because we're on the cheaper model
#endif


来源:https://stackoverflow.com/questions/40589061/purpose-of-define-ing-symbol-as-itself-in-c

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!