Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to print a pound / hash via C preprocessor?

I need help doing the following:

a preprocessor macro label(x) shall output "#x", e.g.,

#define label(x) ...

if I call label(aname), the output shall be "#aname" (w/o quotes)

I know, that the following tries were errors.

#define label(x) #x   // leads to "x"
#define label(x) \#x  // is \"x"
#define label(x) "#x" // is "#x" (but not the content of x") "#otto"

It may exist a kind of escaped # (pound), but I don't know, how to escape...

Edit: I run "gcc -E test -o test.html" to get the output. The point is: How do I print out a hash mark (#) with a makro only using preprocessor's capabilities?

like image 224
tuergeist Avatar asked Sep 06 '09 20:09

tuergeist


People also ask

What does ## mean in C preprocessor?

## is Token Pasting Operator. The double-number-sign or "token-pasting" operator (##), which is sometimes called the "merging" operator, is used in both object-like and function-like macros.

What is ## in preprocessor?

The double-number-sign or token-pasting operator (##), which is sometimes called the merging or combining operator, is used in both object-like and function-like macros. It permits separate tokens to be joined into a single token, and therefore, can't be the first or last token in the macro definition.

What is C preprocessor output?

When the C preprocessor is used with the C, C++, or Objective-C compilers, it is integrated into the compiler and communicates a stream of binary tokens directly to the compiler's parser. However, it can also be used in the more conventional standalone mode, where it produces textual output.

Does C preprocessor do math?

The preprocessor does not do math. The results of preprocessor arithmetic can be used, for conditional preprocessor directives, inside the current preprocessor phase, but substitutions resulting from #defined expressions that are passed to the compiler are text (the replacement list).


2 Answers

The answer is:

#define hash #
#define f(x) x
#define label(a) f(hash)a

then

label(foobar)

creates

#foobar

I found it with the help of all of you, but especially wintermute. Thanks a lot!

(Using gcc 4.3.3)

like image 175
tuergeist Avatar answered Nov 03 '22 01:11

tuergeist


I don't think you can, which is not wholly unreasonable since the output of the C preprocessor should not produce an unquoted '#' because that would indicate a pre-processor directive, and you cannot generate pre-processor directives on the fly like that.

In other words, the C preprocessor is a preprocessor for C (and C++) and not a completely general purpose tool.

Either use an alternative macro processor (m4 is the standard recommendation on Unix-like systems), or go about things differently.

For example, have the macro replacement:

#define label(x)    !@!x

Then post-process the output replacing '!@!' with '#'.

(The imake program uses a similar stunt; the C preprocessor does most of the work, but its output doesn't preserve line breaks needed by 'make', so 'imake' uses the notation '@@\' or thereabouts to indicate where line breaks need to be inserted after the C preprocessor has done its worst.)

like image 26
Jonathan Leffler Avatar answered Nov 03 '22 01:11

Jonathan Leffler