make cctk_Loop.h work in Fortran even if an ANSI C preprocessor is used

Issue #2363 new
Roland Haas created an issue

cctk_Loop.h used constructs like

#define FOO(x) cctk_loop_/**/x

to concatenate identifier names. This only works when using cpp --traditional but not for an ANSI C preprocessor that requires

#define FOO(x) cctk_loop ## x

Cactus’s old header files in cctk_Types.h support both options via an ifdef.

All current option lists use cpp --traditional for FPP and Cactus’s linux built in architecture file does the same, and cctk_Loop.h is (as of 2020-04-03) broken for other reasons (see http://lists.einsteintoolkit.org/pipermail/users/2020-February/007298.html) so this issue has not yet show up.

Comments (3)

  1. Erik Schnetter

    ANSI C preprocessors split the code into tokens and work on tokens. What C considers a token doesn’t work for Fortran.

    The notorious example is that it doesn’t preserve indentation (problem for fixed-format Fortran), or that “//” is string concatenation in Fortran, but introduces a comment in ANSI C, which then ignores the remainder of the line. Other problems come from how strings are quoted, or how numbers with scientific notion are denoted, or that Fortran uses the dot “.” to delimit operators (“x==2.or.x==3”, no floating-point constant in here).

  2. Roland Haas reporter

    Admittedly I have not looked into the actual practicality of this, given that everything does indeed use --traditional. This ticket is solely based on the observation that Cactus' cctk_Types.h file contains explicit code to handle an ANSI C preprocessor which seems to hint that this may have worked once (possibly only for free form F90 code and code that does not use “//”).

    So it is a “make everything behave the same way” type ticket.

    https://bitbucket.org/cactuscode/cactus/src/25ace96251c4d720317afcbe00fa3f9d0646c272/src/include/cctk_Types.h#lines-271

    #if CCTK_ANSI_FPP
    #define CCTK_DECLARE(typ,nam,dim)                       \
      typ nam dim &&                                        \
      integer, parameter :: cctki_use_##nam = kind(nam)
    #else
    #define CCTK_DECLARE(typ,nam,dim)                       \
      typ nam dim &&                                        \
      integer, parameter :: cctki_use_/**/nam = kind(nam)
    #endif
    

    where CCTK_ANSI_FPP is set via magic https://bitbucket.org/cactuscode/cactus/src/25ace96251c4d720317afcbe00fa3f9d0646c272/src/include/cctk_Types.h#lines-241

    /* The empty
       comment in the definition of CCTK_ANSI_FPP will either turn into
       nothing or into white space.  There must not be any add spaces
       around this empty comment.
    
       A traditional cpp will turn it into nothing, an ANSI cpp will turn
       it into white space.  Depending on this, CCTK_ANSI_FPP will either
       turn into a single separate token (which lead to the value 0), or
       into two separate tokens (which lead to the value 1).
    
       This is magic.  */
    #define CCTKi_FPP_A
    #define CCTKi_FPP_B 1
    #define CCTKi_FPP_ACCTKi_FPP_B 0
    #define CCTK_ANSI_FPP CCTKi_FPP_A/**/CCTKi_FPP_B
    

    Thus if indeed an ANSI CPP can never be used, then I would instead try and retarget this ticket to make Cactus abort if $(FPP) $(FPPFLAGS) is an ANSI CPP.

  3. Log in to comment