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;elseif (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 -Evoid 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宏中隐藏.
 可通过转换语句表达式为不带参数的嵌套函数来支持语句表达式.
 但是,带跳进或跳出语句表达式时,会不起作用.


