8

Why does code:

#define EXPONENT(num, exp) num ## e ## exp
EXPONENT(1,1)
EXPONENT(1,-1)
EXPONENT(1,+1)

after preprocessing changes into:

1e1
1e- 1
1e+ 1

and not into

1e1
1e-1
1e+1

? I suspect it might be because -1,+1 are parsed as two tokens (?). However, how in that case obtain the latter result?

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
kwitek
  • 81
  • 4

3 Answers3

4

You're right, -1 and +1 are two preprocessing tokens, hence only the first is pasted to the e.

For me,

#define EXPO(num, sign, ex) num ## e ## sign ## ex

EXPO(1,,1)
EXPO(1,-,1)
EXPO(1,+,1)

worked with gcc-4.5.1.

Daniel Fischer
  • 181,706
  • 17
  • 308
  • 431
  • This works. However, to solve my problem you have changed its description ;-) I need a macro that takes only two arguments, number and exponent... – kwitek Jul 12 '12 at 14:41
  • If that's an unchangeable requirement, I have no idea how to do it. It may be impossible. – Daniel Fischer Jul 12 '12 at 15:02
3

I think the problem you are running into is considered undefined behavior. Per gcc 4.3.2 documentation on concatentation:

However, two tokens that don't together form a valid token cannot be pasted together. For example, you cannot concatenate x with + in either order. If you try, the preprocessor issues a warning and emits the two tokens. Whether it puts white space between the tokens is undefined. It is common to find unnecessary uses of ## in complex macros. If you get this warning, it is likely that you can simply remove the `##'.

See also this answer on SO which exhibits the same problem.

Edit:

I managed to get this to work, but you'll need two macros for + and -

#define E(X) 1e-##X
int main()
{
  double a = E(10); // expands to 1e-10
  printf("%e", a);
  return 0;
}
Community
  • 1
  • 1
  • Thanks. Does that mean that it is impossible to solve my problem with C preprocessor? – kwitek Jul 12 '12 at 14:43
  • @kwitek: Did you try a variant of the last code sample in that answer? –  Jul 12 '12 at 14:46
  • Yes. #define EXPO(x, y) x e y leaves whitespaces, and #define EXPO(x, y) xeb results in string xeb ;( – kwitek Jul 12 '12 at 14:52
-1
#include <stdio.h>
#include <stdlib.h>

#define EXPONENT(num, exp) atof(#num "e" #exp)

void main(){
    double x = EXPONENT(1,-1); 
    printf("%f", x);
}
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70