views:

608

answers:

8

Hello,

Is there a way in gcc/g++ 4.* to write a macro that expands into several lines?

The following code:

#define A X \ Y

Expands into

X Y

I need a macro expanding into

X
Y
A: 

Have you tried something like:

#define A \
X \
Y

?

Jerry Coffin
I did. Still "X Y" in the output.
Michael Rybak
`\\` merely means "it's on the next line", referring to the rest of the macro. All macro's expand to one line, hence Michael's comment on the OP. I too don't think there is a way.
GMan
I should add that the line continuation character isn't a macro only thing per se. The preprocessor will take two lines separated by the backslash character and concatenate them; this is why it appears on one line like I said above. It also means the following is valid (assume a newline after every backslash): `// a comment \\\\\\\\\\\\\\\\\\\\\\!!!` A "multi-line single-line" comment.
GMan
A: 
#define A "X \nY" is this what you want?
Jagannath
No, I don't need a string constant. I need A to expand into two operators separated by a line break. For instance#define A x++; __something special here__ y++;AAnd I'd expect it to expand into:x++;<linebreak here>y++;Instead ofx++; y++;
Michael Rybak
What's wrong with `x++; y++;`? The compiler doesn't care about whitespace.
Carl Norum
@Michael, Then what are trying to achieve
Narendra N
+2  A: 

Why does the spacing matter?

The imake program used in (older?) builds of X11 used the C pre-processor to generate makefiles, but imake program used a special technique of indicating line endings with @@ symbols at the ends of lines, and then post-processed the output of the pre-processor to replace the @@ symbols with newlines.

From this design, I conclude that there is no reliable way to obtain newlines from expanded macros in C (or C++). Indeed, for C, there is no need since:

  • C does not care about newlines compared with white space after the C pre-processor is run, and
  • You cannot generate pre-processor directives from macros etc.
Jonathan Leffler
That's all nice and pretty as long as you're using `CPP` to produce C/C++/other newline-agnostic language result. Very recently I had to generate shell files using C Preprocessor. I assure you newlines matter.
SF.
@SF: In which case you are using the wrong tool for the job. The CPP is, um, the C preprocessor. As such, it follows some strict rules in the C standard, and is presumably optimized for preprocessing C. Get yourself a real macro preprocessor, or write something using a scripting language. Please do not insist that additional features be bolted onto software I use as intended. Similarly, I like being able to buy a crescent wrench that doesn't have a hammerhead attached to the side.
David Thornley
+2  A: 

I'm pretty sure CPP, being designed for C which doesn't care for newlines, and all, can't handle this kind of work. Still you can mark wanted newlines with some special marker string and pass the result through sed or awk to get what you want.

SF.
C doesn't care for tabs either, but you can define a macro whose expansion includes one or more tabs. Lack of newlines is a very specific hole in C macro capability.
Steve Jessop
@Steve Jessop: if you need a general macro preprocessor, use 'm4'. The C pre-processor is designed to meet the needs of the C compiler; it is not, despite its widespread use, a general-purpose macro preprocessor.
Jonathan Leffler
+1  A: 

From the docs:

in the present implementation, the entire expansion comes out on one line

MSalters
A: 

I have the same need. One very good reason for wanting macros to expand into multiple lines is to 'produce' source code from macros that can be debugged. Who likes single stepping 30 times in a macro without seeing new statements for each step ? So if gcc supported the AT&T research cpp extension '#macdef' and '#endmac' to define multiline macros with having to use line continuation characters (thus in practise producing long single line statements) would be great !!!!!

I have also played around with trying to trick gcc cpp to produce newline in the expansion with no sucess :-(

MFredriksson
At least you've got a C-related reason.
David Thornley
+2  A: 

Got it!

#define anlb /*
*/ A /*
*/ B

anlb anlb

V

gcc -E -CC nl.c

V

/*
*/ A /*
*/ B /*
*/ A /*
*/ B
Potatoswatter
Nice trick. I tried it with VC++; while its preprocessor can be instructed to preserve comments in the preprocessor output using `/C`, it doesn't preserve comments in macros, so this all ends up on one line.
James McNellis
A: 

What he wants is a way to make the pre-processor to add a new line

This code for example:

define D_DEFINE(typ) \

struct C_##typ {\

typ d_##typ; \

};\

\

typedef struct C_##typ D_##typ;\

typ* D_##typ##_new(){\

return (typ*) malloc(sizeof(typ));\

};\

The pre-processor would put all in one line:

struct C_MyClass { MyClass d_MyClass; };typedef struct C_MyClass D_MyClass;MyClass* D_MyClass_new(){ return (MyClass*) malloc(sizeof(MyClass));};

and he wants:

struct C_MyClass {

MyClass d_MyClass;

};

typedef struct C_MyClass D_MyClass;

MyClass* D_MyClass_new(){

return (MyClass*) malloc(sizeof(MyClass));

};

Is there or not a way to force the preprocessor to do that?

Axllaruse
The OP's question was quite clear, and there are several good answers. The answer is, no, there is no portable way to get the preprocessor to emit code with newlines because newlines are not significant after preprocessing.
James McNellis