Fortran多行#define宏定义

3
我曾以为C风格的宏定义在gfortran中可以使用?
#define ERROR_CHECKER(msg,stat) \
      IF (stat.NE.0) THEN \
         DO i = 1,BIG \
            IF(msg(i).NE.C_NULL_CHAR)THEN \
               ErrMsg(i:i) = msg(i) \
            ELSE \
               EXIT \
            END IF \
         END DO\
         IF(stat.EQ.1) THEN \
            ErrStat = ID_Warn \
         ELSE \
            ErrStat = ID_Fatal \
            RETURN \
        END IF \
     END IF

但是这个错误毁了我的一天:

IF (stat.NE.0) THEN      DO i = 1,BIG         IF(message
               1
Error: Cannot assign to a named constant at (1)

你知道我在这里做错了什么吗?

其次,问题是:intel fortran是否识别c风格的宏?如果是,则需要编译器标志吗?


2
如果您的扩展名不是:.fpp、.F、.F90、.FOR、.FTN 或 .FPP,那么在 ifort 中您需要使用 -fpp 标志。 - Exascale
1
问题显然是\\在生成的代码中没有产生换行符。(在ifort -fpp中也不起作用,我刚刚检查过了。) - agentp
2个回答

1

不要使用宏,而是将宏转换为函数。这样你就不会过度依赖Fortran编译器是否具有宏功能。

LOGICAL FUNCTION ERROR_CHECKER(msg,stat)
  character*(*) msg(*)
  integer stat
  IF (stat.NE.0) THEN
     DO i = 1,BIG
        IF(msg(i).NE.C_NULL_CHAR)THEN
           ErrMsg(i:i) = msg(i)
        ELSE
           EXIT
        END IF
     END DO
     IF(stat.EQ.1) THEN
        ErrStat = ID_Warn
     ELSE
        ErrStat = ID_Fatal
        RETURN .FALSE.
    END IF
 END IF
 RETURN .TRUE.
 END FUNCTION

在你的代码中
IF (ERROR_CHECKER(msg, stat)) RETURN

编辑:一些较新版本的Fortran有语句分隔符(;)可用。不幸的是,行长度受限制,因此您的宏不能太长,也不能包含多个控制结构。

我一直在尝试类似的东西。但是宏也应该能够工作,我正在寻找解决这个问题的方法。最终,我会遇到强烈推荐使用宏的情况... - user1628622

0

除了这种宏的方法不是好的风格之外,您还错过了生成代码中必要的换行符。这可以通过在宏定义中的每个反斜杠前放置一个分号来解决(第一行除外)。


1
不是这样的,行长度限制仍然会生效。 - Vladimir F Героям слава
确实,一个人需要使用编译器标志来实现无限行长度,但这可能会降低代码的可移植性。 - Raul Laasner

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接