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

d的更好C关闭ctfe的dup

原文

//dmd -betterC

mixin(`void foo(){}`.idup);
 //错误:`'TypeInfo'`不能与`-betterC`一起使用

这会导致mir.bitmanipmir-cpuid中的BetterC回归
我也有类似的问题.用betterC编译时,在CTFEphobos的大多数东西不管用(在dmdldc中,有同样错误)

void main() {
    import std.uni : toLower;
    pragma(msg,"asdfBsdf".toLower);
}

在此讨论,需要修复.
之所以有该错误,是因为在打开BetterC时已版本化了object.didup()的定义,所以ctfe找不到它.
对此很难.
betterC中有idup,只是编译器拒绝运行它.
编译时环境中执行时,不应限制betterC.

建议专门用if(__ctfe)覆盖容易算出来的betterC检查.就像:

int* do_something() {
   if(__ctfe) {
       return new int;
   } else {
       return cast(int*) malloc(int.sizeof);
   }
}
enum e = *do_something();

应该可在编译时允许运行时禁止的东西.
很好观点.CTFE很难,因为即使此时不会运行代码,它仍然需要编译.
没有进入对象符号表的函数,仅用于CTFE编译和运行.如果在运行时引用它们,则抛错误.这是可行的.
或在betterC模式下,逆转绑定为d运行时idup(显然这在以前是有效的).

观点是代码编译得很好.只是没有druntime链接或未生成typeinfo,或运行时依赖,因而不链接.
-betterC开关试检测这些潜在链接器错误,并在编译提前报告它们,以获得更一致和用户友好错误.因为,

if(__ctfe)
//或
mixin
//或
pragma(msg)

等仅涉及编译时工具,从不参与生成代码,因此不应有链接器错误,编译器*应该*知道这一点,而不是导致提前编译错误.

__traits(compiles)
//或
is(typeof())

灰色区域,也不生成代码,因此不应生成链接器错误,也不应生成betterC错误,但考虑到它的使用方式,应该假设里面内容会用来生成代码,因此此时,应返回.

但如果拿不准,'-betterC'目标应该是给出'-defaultlib='相同的输出,只是带编译错误而不是链接器的未定义符号错误.

但这不是问题,CTFE有部分可编译,但不编译部分,如在ctfe时,typeid(x)确实不编译.那么如何"编译"它,仅允许在编译时运行?因此这很难.

很难完美检测druntime,如,如下无编译错误,但有链接错误(使用-betterC):

import core.thread;
import core.time;

extern(C) void main()
{
    Thread.sleep(1.seconds);
}

当然,__traits(compiles)会说,所以这确实是灰色地带.
哦,刚想到一个主意.考虑一下导致问题_dup模板.如果这样:

version(D_BetterC) extern(C) void _dup_UNAVAILABLE_IN_BETTERC();

private U[] _dup(T, U)(T[] a) // 根据后复制的pure nothrow
{
    if (__ctfe)
    { /* ctfe代码*/ }

    version(D_BetterC) {
        _dup_UNAVAILABLE_IN_BETTERC();
        return U[].init;
    }
    else:
    
    // 用typeid的普通代码
}

延迟错误链接器,但标记出问题的函数.可需要时用简单插件完成.
这是带清晰消息的编译器错误.
但这确实改变了idup,使它在__traits(compiles)时返回.这有问题吗?没有.用(D_BetterC)版本代替__traits(compiles).
而且,它不工作.编译时使用模板会使它想链接到符号.除非能区分编译时和运行时用的啥,否则,这不工作.

__traits(compiles)内部使用时,betterC错误似乎会终止编译.
不会打印内容,也不会生成二进制:

extern(C) void main()
{
   int[] arr;
   pragma(msg, __traits(compiles, arr.idup));
}

如下问题,导致该错误.

private string makefoo() {
    if(__ctfe) {
        string a = "b";
        a ~= "c\0";
        return a;
    }
    assert(0);
}

enum foo = makefoo();

extern(C) int main() {
    import core.stdc.stdio;
    printf("%s", foo.ptr);
    return 0;
}

这里的private函数,基于private''if(__ctfe)',显然是仅CTFE的.但编译器不知道.
或可搞个类似'pragma(ct_only)'的语句.
修复
这是权宜之计,但最好,函数不需要版本化代码来适应它们在betterC中的CTFE使用.

相关文章:

  • 新风格网站/收录优美图片官网
  • 张家港哪家做企业网站/小程序流量点击推广平台
  • 在越南做网站需要什么/微信小程序开发多少钱
  • hbuilder网站开发实例/天津网站优化
  • 做网站真实收益/百度总部在哪里
  • wordpress防黑客插件/精准粉丝引流推广
  • 当青训营遇上码上掘金之主题四-攒青豆
  • javaEE 初阶 — 文件内容的读写
  • Linux chattr命令
  • #9文献学习--基于元强化学习的边缘计算快速自适应任务卸载
  • 一篇文章带你学完JavaScript基础知识,超全的JavaScript知识点总结
  • react受控组件和非受控组件区别
  • 拐点检测常用算法总结
  • YonBuilder 应用构建教程之移动端扩展
  • 文本处理工具
  • Virtualbox设置固定IP
  • 基于云计算与深度学习的常见作物害虫识别
  • 数据量大也不卡的bi软件有哪些?