Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Macro without definition in C

What is the use/applicability of macro function without definition:

#ifndef __SYSCALL
#define __SYSCALL(a, b)
#endif

One can find this macro in Linux system in header file /usr/include/asm/msr.h

I also notice macro of following kind.

#define _M(x) x

And only reason to defined this kind of macro that I can think to make code uniform. like in #define SOMETHING (1 << 0). Is there any other hidden(better) use of this kind of macros?

An answer with example will be very helpful. Also can someone provide me a text/link to read about this.

like image 989
Grijesh Chauhan Avatar asked Mar 06 '13 19:03

Grijesh Chauhan


2 Answers

One of the most common case of a macro of this form:

#define _M(x) x

is to provide backwards compatibility for compilers that only supported the original K&R dialect of C, that predated the now-ubiquitous ANSI C dialect. In the original K&R dialect of the language, function arguments were not specified when declaring the function. In 1989, ANSI standardized the language and incorporated a number of improvements, including function prototypes that declared the number of type of arguments.

int f(int x, double y); /* ANSI C. K&R compilers would not accept this */

int f(); /* Function declared in the original K&R dialect */

While compilers that support the original K&R dialect of C are rare (or extinct) these days, a lot of software was written when both kinds of compilers needed to be supported, and macros provided an easy way to support both. There are still a lot of headers laying about that provide this backwards compatibility.

To provide backwards compatibility for K&R compilers, many header files have the following:

#if ANSI_PROTOTYPES
#  define _P(x) x
#else
#  define _P(x) ()
#endif

...

int f _P((int x, double y));

If the ANSI_PROTOTYPES definition has been correctly set (either by the user or by some prior #ifdef logic), then you get the desired behavior:

  • If ANSI_PROTOTYPES is defined, the definition expands to int f(int x, double y).
  • If ANSI_PROTOTYPES is not defined, the definition expands to int f()
like image 105
sfstewman Avatar answered Nov 03 '22 15:11

sfstewman


This is often used with conditional expressions to disable a macro by causing it to be preprocessed to nothing. For example (simplified):

#ifdef DEBUG
#define ASSERT(x) if(!(x)) { abort(); }
#else
#define ASSERT(x) /* nothing */
#endif
like image 21
nneonneo Avatar answered Nov 03 '22 14:11

nneonneo