突破技术
支持复数与s7库
在控制系统,信号处理,图形学和科学计算中广泛使用复数.C一直是编写高性能数字信号处理,嵌入系统和实时信号进程库的偏爱语言.
历史上,在导入C中编译C复数时遇见困难.编译带复杂整的库(如科学s7库)更难,有时甚至不可能.编译这类代码已有了巨大改进,现在几乎可编译任何C语言的复数码.
下面是现在可用D成功编译的简单代码片:
cpp
#include <complex.h>
#include <stdio.h>
#include <assert.h>
struct com
{
int r;
int c;
};
void foo()
{
struct com obj = { 1, 3 };
_Complex double x = { obj.r, obj.c };
//real + im*i
assert(creal(x) == 1.000000);
assert(cimag(x) == 3.000000);
return;
}
int main()
{
foo();
return 0;
}
加深支持C99
指定初化器
导入C现在可编译C指定的初化器.如果你过去试编译包含指定初化器的C代码,嵌套结构初化器,不会支持,导致编译器错误.现已大幅改进和修复.
cpp
struct top
{
int a;
int b;
};
union t_union
{
int f;
int g;
};
struct Foo
{
int x;
int y;
struct top f;
};
struct Bar
{
struct Foo b;
int arr[3];
union t_union u;
};
struct Bar test = {
.b.x = 5,
.b.y = 7,
.b.f = {8, 9},
.arr[0] = 10,
.arr[1] = 11,
.u.f = 13
};
这是简单片段,可作为支持C结构指定初化器的示例.和C一样,可任意深入,D会帮你编译,同时确保结构成员包含期望的数据.
复合字面值
用导入C取复合字面值地址之前是无法编译的.它,已修复,现在可用导入C按左值使用复合字面.
cpp
int *c = &(int){90};
这是一个按90的临时整数初化的整数指针.请放心,你会在c指向的内存地址上读到90.
函数和变量再声明
在C的本地域中,允许函数再声明.现在在编译此类再声明时,不再有编译错误.此外,也加强了全局外部变量再声明.
导入C极大地改进了全局和本地再声明的检查类型.
cpp
/*对变量*/
extern int x;
extern char x
/*对`函数声明`*/
int foo();
double foo();
与C禁止一样,D已大幅改进以确保检查到他们.
C宏
现在可从D导入C语言程序中定义的宏.根据使用场景,可轻松地按标志或函数参数传递这些参数.虽然过去该功能并不总是运行良好,很是在导入并使用D代码时,但已有了显著改进.
除此外,编译器中还实现了多个内置宏.
内置支持,后端与链接胜利
GNU,GCC,CRC内置功能
大多数``GNU的GCC循环冗余检查(CRC)内置功能,已实现.如果在D中使用任何引用它们的C函数,就提供必要的内置实现.
DMD复制后端符号
再声明全局变量最初有问题,因为这常导致符号表中的符号重复,特别是在DMD中.已修复它,使D可与依赖跨多头的冗余的全局声明的大规模C库链接.
静态链接
之前很难从C模块创建静态库,特别是涉及前向声明的模块.为此工作,现在可成功地从C模块创建静态库.
cpp
static void static_fun();
void lib_fun()
{
static_fun();
}
static void static_fun()
{
}
创建静态库时,需要传递-lib``命令行选项.dmd -lib file.c现在支持该工作流.