d修复导入c的问题
原文
void my_fatal()
{
*((volatile unsigned int *) 0) = (unsigned int) 0xdeadbeefUL;
}
导入C
中忽略易失.
可这样替代:
static void* p;
*(unsigned int*)p = (unsigned int) 0xdeadbeefUL;
导入C
赋值数组复合字面给使用GC分配
的指针
void fn()
{
void *p = (int[1]){0};
}
这使用_d_arrayliteralTX()
为数组
分配存储
此外,用-betterC
时,因为"TypeInfo
不能与-betterC
一起使用",而无法编译
在其他
编译器中,字面有"auto"
存储持续时间,因此它与使用局部变量
相同.
此测试检测是否是用GC
分配指针
:
int test()
{
void *prev;
for (int i = 0; i < 2; i++)
{
void *curr = (int[1]){0};
//在两个`循环`迭代中应有相同地址
if (i == 0)
prev = curr;
else
if (curr != prev) return 1;
}
return 0;
}
_Static_assert(test() == 0, "");
int main()
{
return test();
}
已修复.
导入C的属性候选,2
不能取字面地址:这里
void fn()
{
int *a = &(int[1]){0};
int *b = &(int){0};
}
第一行编译成功了,第二行不行.
在CTFE
中使用复合字面数组
为指针
会导致"无效指针的解引用
",这里
int fn()
{
int *p = (int[1]){0};
*p = 0;
return *p;
}
_Static_assert(fn() == 0, "");
int main()
{
return fn();
}
在CTFE
外工作.
虽然可使它工作,但它是无效的C11
代码.
现在在ctfeexpr.d(578)
上给出断定
错误.
如下不编译
union nk_page_data *pd = (union nk_page_data*)((void*)((char*)(1 ? (tbl): &((union nk_page_data*)0)->tbl) - (__builtin_offsetof(nk_page_data,tbl))));
这是化简版:
#define NK_OFFSETOF(st,m) (__builtin_offsetof(st,m))
#define NK_ALIGNOF(t) NK_OFFSETOF(struct {char c; t _h;}, _h)
struct nk_command{};
void test()
{
const int align = NK_ALIGNOF(struct nk_command);
}
// 用cpp -P -E
void test()
{
const int align = (__builtin_offsetof(struct {char c; struct nk_command _h;},_h));
}
GCC编译
,但导入C
不编译.
现在编译
了.
交叉编译
交叉编译
时,经常要用不同预处理器
来获得正确
的平台定义.在此不用CC
环境变量,也没有开关
.
当然,dmd
不会做太多的交叉编译
,但如果可完成,那就太好了.
dmd
交叉编译使用了-os=windows
,-os=freebsd
等开关,我一直都在用它.
但你是对的,交叉编译.c
文件有个问题,你如何在另一个
平台上运行C预处理器
?
导入C名字冲突
假设a.c
包含#include<stdio.h>
,b.c
也包含它.
然后D文件同时导入a和b.
现在像printf
此函数会出现名字冲突.
这在D中是正常的,因为不同
模块有自己的名字空间.但是在C中,不同头文件
包含不同的东西是很常见的.一个导入保护
可保持它在那里,但是在D中这并不管用.
我建议放importC
符号在神奇
模块中,然后别名它们公开/选择性
地导入到使用包含
导入的D模块中.然后引用相同的C名字空间,同时保持D名字空间
的卫生性并避免虚假冲突
.
无法编译示例
import std.stdio;
import square;
void main()
{
int i = 7;
writefln("%s的平方为%s", i, square.square(i));
}
示例
刚试过了,它工作正常,因为已重命名square.c
为functions.c
编译问题
我在ManjaroLinux
上尝试用DMD2.101.1
编译Nuklear
库时,不小心碰到了同样的八哥
.
根据assert.h
的错误消息和源代码
,我认为ImportC
试图使用以下assert
的定义:
# define assert(expr) \
((void) sizeof ((expr) ? 1 : 0), __extension__ ({ \
if(expr) \
; /* empty */\
else \
__assert_fail(#expr,__FILE__,__LINE__,__ASSERT_FUNCTION);\
}))
语句式
GCC
把:
{语句; 语句;}
当作表达式.
__PRETTY_FUNCTION__
在_ASSERT_FUNCTION
宏中隐藏.
可通过转换
语句表达式为不带
参数的嵌套
函数来支持
语句表达式.
但是,带跳进
或跳出
语句表达式时,会不起作用.