8

For learning and demonstrating, I need a macro which prints its parameter and evaluates it. I suspect it is a very common case, may be even a FAQ but I cannot find actual references.

My current code is:

#define PRINT(expr) (fprintf(stdout, "%s -> %d\n", __STRING(expr), (expr)))

and then:

PRINT(x & 0x01);

It works fine but I am not sure of the legal status of the __STRING macro, specially since it is in the private __ namespace.

So, my questions:

  1. Is there a better way to write this macro?
  2. Is __STRING standard/great/evil?
  3. How to use existing search tools to find about __STRING? SO's search engine just searches anything containing string :-(
Coral Doe
  • 1,925
  • 3
  • 19
  • 36
bortzmeyer
  • 34,164
  • 12
  • 67
  • 91
  • I've had similar problems searching in the past. ".net" used to be a big one. – aib Dec 18 '08 at 10:27
  • 1
    You can use google to search StackOverflow by using google's site: argument :) e.g. "__string site:stackoverflow.com" (which didn't return anything). – codelogic Dec 18 '08 at 10:35

3 Answers3

13

Something like

#define PRINT(expr) (fprintf(stdout, "%s -> %d\n", #expr, (expr)))

is probably what you want. # is the stringification operator.

codelogic
  • 71,764
  • 9
  • 59
  • 54
11

You can use the # preprocessor token which converts the parameter following it to a string literal:

#include <stdlib.h>
#include <stdio.h>

#define STR(x) #x
#define PRINT(expr) (fprintf(stdout, "%s -> %d\n", STR(expr), (expr)))

int main(void)
{
    int x = 7;

    PRINT(x & 0x01);

    return EXIT_SUCCESS;
}
  1. It's definitely not standard, and this is the first time I've come across it; not surprising as it doesn't seem to do much more than the STR() macro above, at a first glance.

  2. Google seems to work fine.

Eric Postpischil
  • 195,579
  • 13
  • 168
  • 312
aib
  • 45,516
  • 10
  • 73
  • 79
  • Indeed, just using #expr in the macro definition works fine. But, then what's the point of the __STRING macro that you find in many places (such as assert() source code)? – bortzmeyer Dec 18 '08 at 10:20
  • __STRING is just a wrapper around #. It's defined in cdefs.h – codelogic Dec 18 '08 at 10:22
0

It is glibc who has been providing __STRING since (at least) version 1.04 (1992-09-03), maybe earlier.

/usr/include/sys/cdefs.h:

#define __CONCAT(x,y)   x ## y
#define __STRING(x) #x

They were both used in glibc back then. Currently, __STRING is not used in glibc, but is kept there for app use.

On Linux, you may rely upon these. IIUC, __STRING and __CONCAT were adopted in NetBSD 1.3; Solaris provides neither. Other OSes may vary.

jabba
  • 1
  • 1