我正在重新设计一个用 C 语言编写的大型科学应用程序的内部结构,以便将自行开发的 MyComplex
类型及其相关例程替换为使用C99 复杂
类型。
有些很简单,比如
#ifdef HAVE_COMPLEX_H
#include <complex.h>
#define double complex MyComplex
#define ComplexAddition(a, b) ((a) + (b))
#define ComplexConjugation(a) (conj(a))
#else
/* very old code, used everywhere in the project */
struct MyComplex { double re, double im };
typedef struct MyComplex MyComplex;
MyComplex ComplexAddition(MyComplex a, MyComplex b) { ... }
MyComplex ComplexConjugation(MyComplex a) { ... }
#endif
这一点有效,我对此很满意,但有些例程会查看 MyComplex
结构内部,所以我认为我很聪明,并替换了每次出现的 c.re
与 RealPart(c)
其中
#ifdef HAVE_COMPLEX_H
#define RealPart(c) creal(c)
#else
#define RealPart(c) c ## .re
#endif
(与 ImagPart(c)
和 im
成员类似)。
如果定义了 HAVE_COMPLEX_H
,则效果非常好,但如果我尝试在未设置 HAVE_COMPLEX_H
的情况下进行编译,我的 Mac 上的 Clang 编译器(clang 7.3.0)会显示:
utils.c:13505:9: error: pasting formed '].', an invalid preprocessing token
RealPart(m[row][dim - 1]), ImagPart(m[row][dim - 1]));
^
./utils.h:39:23: note: expanded from macro 'RealPart'
#define RealPart(c) c ## .re
^
utils.c:13505:36: error: pasting formed '].', an invalid preprocessing token
RealPart(m[row][dim - 1]), ImagPart(m[row][dim - 1]));
^
./utils.h:40:23: note: expanded from macro 'ImagPart'
#define ImagPart(c) c ## .im
^
类似地,GNU 4.2.1 编译器(在 OpenBSD 上)说
utils.c:9968:1: error: pasting "sum" and "." does not give a valid preprocessing token
utils.c:9968:1: error: pasting "sum" and "." does not give a valid preprocessing token
utils.c:10059:1: error: pasting "]" and "." does not give a valid preprocessing token
我似乎无法正确地获得宏定义,并且我开始怀疑是否有可能创建一个扩展为结构成员的宏。
这可能是我忽略的简单事情......
最佳答案
问题在于 ##
连接字符串,而 RealPart()
和 ImagPart()
的参数不是字符串。
正确的宏定义(当HAVE_COMPLEX_H
未定义时)是
#define RealPart(c) c.re
#define ImagPart(c) c.im
这对我来说有点太明显了。
关于c - 引用结构成员的宏,自行开发的复杂类型到标准 C99 复杂类型的转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37736613/