67780

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

Question:

I came across some <strong>C</strong> 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 <strong>C</strong> compilers out there?

Answer1:

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

Answer2:

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.

Answer3:

This pattern is also useful for feature-detection of registers in microprocessors, as in <a href="https://stackoverflow.com/q/40589061/102441" rel="nofollow">this question</a>. 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

Answer4:

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 <a href="http://pubs.opengroup.org/onlinepubs/000095399/basedefs/netinet/in.h.html" rel="nofollow">the relevant POSIX spec</a>, quoting:

<blockquote>

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.

...

</blockquote>

Recommend

  • How to measure CPU and memory usage of F# code?
  • Error on loading bootstrap loader, using django (not found the css)
  • Any MQL4 programmers? What is wrong with this code?
  • Toolbar search local data, retain value in cell even after searching
  • How can I use Angular4 *ngFor to create a data table?
  • How do I add a trailing slash for Django MPTT-based categorization app?
  • how to ignore files when finishing private ClearCase branch?
  • Is there a way to remove a script from a doc (using the new doc embedded script)
  • SQL Merge 3 tables by date where some dates are missing
  • Cannot get Django 1.7 Migrations to detect proper changes to my DB.
  • How to gracefully stop python unittest?
  • Trying to get lotusscript json reader
  • Django staticgenerator vs CACHE_BACKEND
  • How to make infinite threaded comments
  • Hiding prices based on visitor location backend bug in Woocommerce
  • Joining across databases with dbplyr
  • List using with references, changes behavior when used as a member
  • CABasicAnimation creates empty default value copy of CALayer
  • MVC3 Extension for ValidatorMessage
  • Compiling and linking NASM and 64-bit C code together into a bootloader [duplicate]
  • Was there ever a proposal to include the URL fragment into the HTTP request?
  • Unable to connect to Azure MySQL Database through Azure Function - C#
  • How to get the Owner of the ContextMenu (from Silverlight 4 toolkit)?
  • How can I filter an array of dictionaries in 'updateSearchResultsForSearchController' to s
  • Multiple canvases (pages) in Fabric.js
  • content must have a ListView whose id attribute is 'android.R.id.list'
  • Facebook Error (#200) The user hasn't authorized the application to perform this action (PHP)
  • Java Collections.shuffle() weird behaviour [closed]
  • Request Access Token in Postman for Azure Function App protected by Azure AD B2C
  • How to resolve this in PHPUnit where it is asking me to set KERNEL_DIR in my phpunit.xml?
  • Stop an element moving with padding on hover
  • Find angle of point on circle
  • Create an average of multiple excel chart without the data source
  • 'url' requires a non-empty first argument. The syntax changed in Django 1.5, see the docs
  • how do i compare two rows and store the similarities of the two rows in another column
  • how to run ejabberd with Erlang on Heroku?
  • How to use Streams api peek() function and make it work?
  • `$http:badreq Bad Request Configuration` - from angular post method, what is wrong here?
  • Create/delete users from text file using Bash script