当前位置: 首页 > article >正文

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


http://www.kler.cn/a/10263.html

相关文章:

  • WPF 应用程序中使用 Prism 框架时,有多种方式可以注册服务和依赖项
  • windows 11编译安装ffmpeg(包含ffplay)
  • 计算机网络分析题
  • 动态规划与贪心算法:核心区别与实例分析
  • 微服务电商平台课程三:搭建后台服务
  • 万字长文解读深度学习——卷积神经网络CNN
  • MySQL日志
  • 如何驯化生成式AI,从提示工程 Prompt Engineering 开始
  • Day939.如何小步安全地升级数据库框架 -系统重构实战
  • 银行数字化转型导师坚鹏:ChatGPT解密与银行应用案例
  • 鸟哥的Linux私房菜 学习 Shell Scripts
  • 【CSS】实现梯形
  • C语言实例:求一个整数的所有因数,创建各类三角形图案(代码+思路)
  • AB测试基本原理
  • t-SNE进行分类可视化
  • 【SpringMVC】7—文件上传
  • 详细讲讲Java线程的状态
  • 林长制信息系统主要建设思路
  • Java实现图片缩放裁剪,图片像素比例变更,批量转换图片像素比
  • 遗传算法优化深度信念网络DBN的分类预测,GA-DBN分类预测
  • C++ 的fcntl函数
  • ChatGPT搭建语音智能助手
  • 工作中英语学习的几个阶段
  • Three.js教程:第一个3D场景
  • 【MyBatis Plus】003 -- 配置(基本、进阶、DB策略) 条件构造器
  • Linux下使用ClamAV病毒查杀