c - 引用结构成员的宏,自行开发的复杂类型到标准 C99 复杂类型的转换

标签 c unix struct concatenation c-preprocessor

我正在重新设计一个用 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.reRealPart(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/

相关文章:

go - 嵌入式结构还是嵌套结构?

c++ - 如何将匿名 C++ union 与匿名结构一起使用

c - linux上实现链表的C程序从文件读取数据出错

c - 如何使用 fget 防止缓冲区溢出?

windows - SCHTASKS.exe 的参数生成器

linux - 将多个 bash 脚本作为单独的作业启动

c++ - 什么类型的指针操作

c - 为什么我的 strcpy() 出现段错误

c - 如何在 UNIX 中为 C 程序编写 makefile

c - 返回结构实例的函数