我想使用<complex.h>
库来加快某些计算的速度,其中可能包括多达20个复杂元素和运算(+-* /)。但是,我的同事声明了一个struct:
struct complex {
double a;
double b;
};
由于与上述结构冲突,因此无法使用来自库的complex
宏。
问题是,由于对当前项目的巨大影响,我无法更改结构的名称。我尝试改用_Complex
宏,并删除了#include <complex.h>
标头,但它起作用了,但是_Imaginary_I
,_Complex_I
或I
不起作用。
#include <stdio.h> /* Standard Library of Input and Output */
// #include <complex.h> /* I want to remove this */
int main() {
struct complex
{
double a;
double b;
};
double _Complex z1 = 1.0;// + 3.0 * _Complex_I;
double _Complex z2 = 1.0;// - 4.0 * _Complex_I;
// none of these work
double _Complex z = CMPLX(0.0, -0.0);
double _Complex z3 = 1.0 + 1.0 * _Imaginary_I;
double _Complex z4 = 1.0 + 1.0 * _Complex_I;
double _Complex z5 = 1.0 + 1.0 * I;
printf("Starting values: Z1 = %.2f + %.2fi\n", creal(z1), cimag(z1));
}
我期望有一种区分库中的复杂宏和定义的复杂结构的方法。遗憾的是我无法更改结构,所以事情变得异常复杂。
我的__STDC_VERSION__
是201112L
,而__VERSION__
是“ 4.2.1兼容的Apple LLVM 10.0.1(clang-1001.0.46.4)”。
答案 0 :(得分:8)
C标准预期会出现此问题,并专门为此提供了一个条款7.3.1p7:
尽管有7.1.3的规定,程序可能仍未定义,然后可能会重新定义宏
complex
,imaginary
和I
。
这意味着,您可以执行以下操作:
#include <stdio.h>
#include <complex.h>
#undef complex /* after including complex.h, before declaring struct complex */
//#include <header_that_defines_struct_complex.h>
struct complex
{
double a;
double b;
};
现在,您的代码可以毫无问题地使用struct complex
和double _Complex
了,并且可以访问<complex.h>
中声明的复杂数学函数。
int main(void)
{
// this should all be fine now
double _Complex z = CMPLX(0.0, -0.0);
double _Complex z1 = 1.0 + 3.0 * _Complex_I;
double _Complex z2 = 1.0 - 4.0 * _Complex_I;
double _Complex z3 = 1.0 + 1.0 * _Imaginary_I;
double _Complex z4 = 1.0 + 1.0 * _Complex_I;
double _Complex z5 = 1.0 + 1.0 * I;
printf("Starting values: Z1 = %.2f + %.2fi\n", creal(z1), cimag(z1));
return 0;
}
但是请注意,即使它们在内存中的布局可能相同,也无法使struct complex
自动转换为double _Complex
或与if (0)
“兼容”。您将需要手动来回复制。
答案 1 :(得分:2)
或者,您可以重新定义the_other_colleagues_header
#define complex my_complex
#include <the_other_colleagues_header>
#undef complex
#include <complex.h>
现在,在.c文件中,您可以同时使用complex
和my_complex
,其他人仍可以照常使用struct complex
。或为complex.h
写一个包装,然后从您的应用中调用
但是更好的解决方案是要求其他同事更改名称。使用标准名称通常是个坏主意
答案 2 :(得分:2)
您的实际问题是
my colleague has declared a struct:
struct complex {
double a;
double b;
};
解决此问题。
解决该问题的所有其他方式将导致事实上未记录的依赖,撤销标准C功能-宏{{1的定义}}。您的组织要做的最好的事情可能是“在我们的编码标准的第4页[您有编码标准吗?],它指出您必须在complex
之后#undef complex
,然后您之后必须#include <complex.h>
”。您的组织实际上能做到的几率是多少?然后确保程序中的每个人都知道吗?
最有可能的是,他们不会为此付出努力,甚至不会接近。
您将获得一些未记录的部落知识。
再次,您的组织是否有书面的编码标准,并且实际执行它们?如果您不能同意,那么您确实确实需要立即解决问题的根本原因,而不是将其埋藏,以免将来引起更严重的问题。
该#include <stomps/on/complex.h>
不仅创建了撤消标准C功能的依赖关系,而且还创建了对struct complex
指令和#include
语句的排序依赖关系。没有真正的方法知道如果不严格遵循这些依赖关系会发生什么-无法排除未来几年的奇怪结果和无法解释的故障。
是的,使用#undef
取消宏的定义是合法的,而不是那么困难。但是当某人不这样做或这样做顺序错误时会发生什么情况?
正确地编写和维护软件就很难了。故意做充其量可疑的事情,不要在程序的整个生命周期中加倍费力。