2

I want to be able to do this in my preprocessor macros

#define dble double
/* Just something that converts x to a double precision float. 
   static_cast used as an illustration: */
#define dble(x) static_cast<double>(x)

I know that overloading is not allowed by the C standard preprocessor. I also know that variadic arguments like

#define dble(...) 

requires at least one argument, and omitting the parenthesis is not allowed. Even by the insight of that I cannot let go of the feeling that it must be a way to solve this problem. Do anyone have any smart ideas how it can be done?

Example of use:

dble x;
x = dble(3);

Background: I am actually interested in using the C preprocessor for my Fortran code. I want to develop a simplified notation for variable declarations. DBLE would expand to DOUBLE PRECISION for standalone applications, or REAL(C_DOUBLE) if I am compiling for C-interoperability for a library with C interface. However, DBLE is a so called INTRINSIC in Fortran. DBLE(3) casts 3 to a double precision float. In standalone mode it would be 3.0d0. In C-interoperability mode it would be converted to 3.0_C_DOUBLE.

Brian Tompsett - 汤莱恩
  • 5,753
  • 72
  • 57
  • 129
  • 1
    Wouldn't it be a lot easier just to `#define dbl double` or use some other abbreviation ? – High Performance Mark Nov 09 '12 at 10:44
  • Why not just have c_double everywhere? Or even better just some other integer constant you set at the top module, be it using preprocessor or not? Dble() as such is more or less deprecated. – Vladimir F Героям слава Nov 09 '12 at 11:10
  • 1
    Another option is to use conditional compilation of modules. Just create two modules with the same name and entities (containing e.g. the `KIND` of your types), then compile one of them depending on the case at end. Notice that, this solution just involves modifications to the build-system and does not require a pre-processor. – Massimiliano Nov 09 '12 at 11:21
  • I agree that the DBLE intrinsic is deprecated. I would actually replace DBLE(x) with REAL(x,KIND=C_DOUBLE) in the case of C-interoperability. maybe the best solution is to give up on DBLE as a variable type and use DOUBLE, DBL, REAL64 instead. But... I just want to make sure before I give up that there is no solution, at all, to my problem as stated above before. I am looking in /usr/include/tgmath.h right now. Lots of preprocessor tricks in here! – user1811679 Nov 09 '12 at 12:28

2 Answers2

0

If you're using static_cast - you're already in C++ world, wich allows you to use double(x). So defining dble double will work.

For more complex cases - well, cpp isn't designed to handle that. Maybe another preprocessor combined with regular expressions might help.

keltar
  • 17,711
  • 2
  • 37
  • 42
0

The preprocessor can handle different number of arguments, but the implementation for such a thing is a bit tricky, especially for the case of distinguishing 0 and some arguments. In P99 I have macros for C99, if you are more interested in C++ (there is no such thing like C/C++, BTW) have a look into boost.

With P99 you could do something like this

#define dble(...) P99_IF_LT(P99_NARG(__VA_ARGS__), 1)(double)(static_cast_double(__VA_ARGS__))

where for C99 I would use a compound literal for the replacement of C++' static_cast

#define static_cast_double(X) ((double){ 0 } = (X))

but this would be a debade of its own rights.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177