Sam
Sam

Reputation: 27

C preprocessor macro: concatenation (example for Fortan90)

I am stuck with the following problem:

I have the two following correct working macros (expanding to Fortran90 code):

#define ld_dx(A)   (  (A(ixp1)-A(ix  ))/(dx)  )
#define rd_dx(A)   (  (A(ix  )-A(ixm1))/(dx)  )

(Note: these macros depend on the following additional macros:

#define ix    2:nx-1
#define ixp1  1+ix+1
#define ixm1 -1+ix-1

And they depend also the declarations:

integer, parameter :: nx = 100, dx = 1

)

In my code I can use these macros by a call as for example

X = X + ld_dx(Y)

or:

X = X + rd_dx(Y)

Now I would like to be able to call ld_dx(A) by writing d_dx(A,l) instead and rd_dx(A) by writing d_dx(A,r). The example would therefore look like this:

X = X + d_dx(Y,l)

or

X = X + d_dx(Y,r)

=> I am looking for a CPP macro that can provide this syntactic sugar (to get as close as possible to the mathematical notation). <=

The most straightforward thing to do would be:

#define d_dx(A,s)  s ## d_dx(A)

Unfortunately this does not work. CPP transforms

d_dx(Y,l)

into:

l ## Y)

I tried many things by studying the other CPP concatenation related questions, but I could not figure it out. Thank you very much in advance for some help!

Sam

PS: Note it would also be fine for me to rename the macros 'ld_dx(A)' and 'rd_dx(A)' into 'dl_dx(A)' and 'dr_dx(A)' This regarding, the most straightforward thing to do would be:

#define d_dx(A,s)  d ## s ## _dx(A)

Unfortunately this does not work neither: CPP transforms

d_dx(Y,l)

into:

d ## l ## _dx(Y) 
  1

Error: Expected a right parenthesis in expression at (1)

I.e. the concatenation is simply not performed.

Upvotes: 0

Views: 1211

Answers (2)

cup
cup

Reputation: 11

Try without spaces. Some preprocessors ignore spaces on either side of the ##, others do not.

#define d_dx(A,s)  d##s##_dx(A)

Upvotes: 0

fizzer
fizzer

Reputation: 13796

#define PASTE(x,y) x##y
#define d_dx(A,s) PASTE(s,d_dx)(A)

Token pasting (## operator) and stringizing (# operator) suppress substitution of adjoining arguments, so you have to do it in two steps.

Upvotes: 2

Related Questions