d的3月会议

Martin:LDC已准备好下个主要版本.
改变extern(D)调用约定,不再反转形式参数.直到最近,DRuntime编译器间还有相互依赖.当有人修复矮人发射时,尤其有问题.

一个问题是,带多个参数并假定参数在特定寄存器或栈槽中的裸asm函数会中断.必须改变Phobos,使LDCPhobos和上游Phobos间有差异.如果DMD可效仿,那就更容易了.

伊恩

弃用

Iain一直在结束已弃用和遗忘弃用期,并为没有的弃用功能添加结束日期.他重复了几个示例,其中一些现在是错误的.Walter查询了复类型的状态.Iain说已弃用他们了,但现在还有一个日期.
在这次讨论中,Iain记得他想在std.complex中加toNative.尽管库实现与C类型是二进制兼容的,但具两个双精结构可能不像C复类型那样按参数传递.这时,该toNative函数可确保兼容.

域结构

Iain在迭代弃用功能中提到区间接口.这导致了域构域类类型的对话.在实例级scope foo=new Foo成为公开强制栈分配前,它开始作为类型声明的一项特征,如,域 类 Foo{},含义是所有Foo实例都在栈上分配.

这有组合问题(如果类型成员是scope类型,则该类型也是域类型).最终,每个人都同意弃用域类型.(从那时起,已经合并了两个PR,它们不赞成struct/unionenum声明及类声明的域,这里,与这里).

Martin查询Iain在上游提交的一系列PR,Iain回答说他一直在测试各种目标(BigEndian目标,严格对齐目标等),导致他在DRuntime中发现了一些回归.

更改DMD词法分析器

Razvan召集了几个学生,致力于将DMD集成为dscanner的库.替换出现的libdparse,但表明他们需要修改前端,来提供与使用libdparse的工具所期望的接口相匹配的接口.

第一个变化是为词法分析器创建区间接口.Walter要求移动区间接口新模块,而不是对词法分析器搞侵入性的更改.Razvan说这不是问题,但确实需要更改词法分析器.具体来说,DMD会删除空格,换行符和注释,但libdparse不会,因此需要添加代码到词法分析器中,以便DMD用作库时不会删除它们.Walter建议尽量为新代码前端创建libdparse模块,以避免加版本化块词法分析器.拉兹万同意.

DIP1008和火卫一

在他的SAOC2021项目(用模板替换DRuntime勾挂)中,TeodorDutu遇到了有时替换抛出异常的勾挂会导致链接器错误(这与混合使用不同开关编译对象时的模板发射有关).前进的唯一方法是使用-dip1008编译d运行时和d标准库.可惜,DIP1008要求在抓到异常在时不能逃出catch块,但Phobos有时通过保存异常变量返回异常来完成.这避免了用-dip1008编译.

Razvan说如何解决,不明显.克隆异常要求用户释放内存,不好.-dip1008此外,当启用分配栈跟踪时,DRuntime仍用GC分配异常(正如Razvan在他于2019年提交,现已关闭的PR中首次发现默认启用-dip1008,这里).

Martin指出,跟踪拆解时也用GC.对此,Walter最终要求Razvan确保存在与RazvanPR相关联的Bugzilla问题链接.

引用计数

通过旧的DRuntime拉取请求,Razvan发现几个PR添加了引用计数的东西(RCArray,RCPointer等),当时引用计数D社区的热门话题.D引用计数的问题在限定符的传递性(如,不能引用计数不变对象).Razvan记得他为存储类起草了DIP__metadata,这里.

在关于DIP的论坛讨论中,TimonGehr指出了它的两个基本问题,这里.最终,Razvan的进展停滞了,未提交DIP.

会议上,说想听听社区现在对该DIP的看法,但想先知道这是否仍然重要.涉及引用计数不变的各个方面讨论:更严格形式的C++mutable(以类似__metadata的形式:不是类型|对象状态的一部分,可能存储对象指针前等),为什么允许从pragma(crt_constructor)修改不变变量是不好,用extern(C) shared static this替换pragma(crt_constructor)的利弊(反之,在没有DRuntime时允许初化不变).

使malloccalloc@trusted

Razvan接着提出了两年前的DRuntimePR,这里,用于使malloccalloc@trusted.本打算合并它,但Iain删除了automerge标签.Razvan问为什么不能合并.Iain说最后一次评论和应用自动合并之间有20个月的时间.PR有很多讨论,所以Iain想给它一些时间来消化它,并在必要时重新开始讨论,以防止问题,但两周后发现有问题.

于是伊恩在会议上触发了新的讨论:malloc真的值得信任吗?对此有很多意见:从中得到了什么?两者都需要不安全无类型内存转换;calloc更强,因为它初化了内存;malloc特定情况下可能是安全的,如在原位时;或无类型时可能不是,因为它不带类型信息等等.
最后,Andrei断言malloccalloc是不安全的,因为他们使用无类型内存且无法绕过它.Walter建议添加Andrei的答案到PR讨论中,并且PR已关闭.Andrei提议在PR线程中陈述该论点,但不关闭它,以便有人可提供引人注目的代码示例来展示如何使malloc可信任.

Razvan这样做了,触发了更多讨论:
讨论
最后,沃尔特做出了最终决定:
决定

丹尼斯,科佩尔
Dennis要求澄清几个相互矛盾PR规范,这些PR旨在澄清过大的移位(如,移动3332位值)会怎样.
沃尔特解释说,这不是未定义行为(可能导致"发射核导弹"或其他东西),但比这更软.它要么会变成0,要么会包装,所以它应该是"实现定义".

丹尼斯问马丁这时LDC(LLVM)优化器做了什么(基于C).MartinLLVM文档指定其为毒值,在相同的文档中定义,有时可能导致未定义行为.Walter指出,编译器可选择删除指定为未定义行为的代码,对过度移位,这不对.

普遍认为"实现定义"是要走的路.

带域的栈上数组

在许多情况下,Mathias都希望可用scope来在栈上分配动态数组,就像使用它在栈上分配类一样,如,scope c=new MyClass.他按类型安全可变参数函数包装分配,但你不能连接它们.沃尔特说很合理.Dennis已打开了Bugzilla,这里.

Mathias说,如果他有时间,可考虑实施它.

-preview=in

同意启用-preview=in应该是默认行为,但应该总是暗含ref而不是让编译器决定.上次
extern(C++)工作是个问题.DRuntime中的标准C++绑定与DMD测试套件中的绑定间存在些差异,因此把内容放在DRuntime中.他指出,包含DRuntime和D前端单个存储库会很有用.

另一个问题是in用作opApply中的闭包参数,in也必须与foreach变量一起使用.沃尔特说有道理.

推导闭包参数的存储类

推导闭包参数存储类,更易写代码.指出了Bugzilla中的老问题及链接的讨论线程(后面2个链接),对闭包参数是否应推导ref有不同意见.那些想要的,按C#中的调用点考虑ref,但在D中,不是在调用|而是在闭包中的参数上使用它.Mathias没啥用.它阻止传递闭包给默认值为ref来避免复制等的std.algorithm.

这里这里

Mathias很想要这个,但因为重载时"有点棘手"而推迟了它,但他认为这是应拥有的.可在邮件列表中讨论.

-checkaction=context应该是默认值

-checkaction=context默认对语言有益,但目前已被破坏.可惜,最近一次变化不同的方式打破了它.应为此找到解决方案.该功能很简单,一旦开始使用它,你就回不去了.

Dennis指出,不使用的一个原因是,它会增加编译时间,而Mathias说这不重要.

推导私有函数属性

Mathias认为推导私有函数很好.当前阻碍属性推导不适用于递归函数.他认为解决方案很简单:应该假设函数具有所有属性;如果递归,其余代码帮助推导属性.沃尔特说有道理;可推导属性越多越好.

Andrei指出,如果添加来可扩展属性,应该小心,因为这会阻止它工作.他还提到,由于可能的栈溢出,关于递归函数的安全性,可能有很简单的论点.

Martin建议需要评估编译时成本.沃尔特说这是合理观点,但认为只能忍受它.有这么多属性,推导越多,用户体验就越好.Martin说,只要编译时间不加倍,就可了.

Andrei指出,已经有研究,如Java,表明人们一般不编写属性.更多推导是要走的路.

别名

Mathias说过早地在编译器解析别名,导致丢失了别名赋值的名字.如,在错误消息中,你看到的是别名,而不是别名自身.它还会造成可见性问题.有时想为私有设置公开别名,但不能这样,因为编译器可直接看到别名.

Walter可见性是特性,而不是错误.这是深思熟虑的决定.允许私有符号公开别名违反了封装.Mathias提供了他公司的用例,在该用例中,他们想在结构体中隐藏私有的getter函数aliasthis,即允许子类型化但禁止直接访问getter.Walter认为别名允许直接访问getter,并在类型系统中创建漏洞.

Mathias认为它都必须在同一个模块中完成,并且由于在模块域内private,认为不会破坏封装.
Razvan建议,如果有人想在公开别名后面隐藏私有符号,他们应在公开函数中包装私有事物.Walter同意了,要求示例.

阿里
Ali说他设法转换他的一个程序为SSH,复制自身到服务器并像rsync一样工作.
Ali的一位同事是Rust爱好者.他们要火拼.

沃尔特

ImportC

Walter报告说ImportC进展顺利,他修复了一堆ImportC错误.可惜,有些错误是难以解决的,可能不得不忍受它们.传递常就是示例:C没有它,但ImportC有.有人在C标头(可变对象的const指针)中发现了导致编译时错误案例.沃尔特不确定这是否可解决.

ImportC已发展到需要启动预处理器地步.没有编译器支持运行预处理器是严重用户体验问题.Iain担心如果D编译器正在调用C预处理器,可能调用的不是正确的.这导致了关于调用|拥有预处理器的讨论.

Martin提出了LDC(等其他编译器)中ImportC的与ImportC如何处理C头文件有关的潜在问题.简而言之:多个D模块中导入相同标头声明导致C的重复.他说ImportC可以按D模块对待每个C标头.
Iain提出了一个他认为难以解决ImportC问题.沃尔特已经修复了它.这里

Bugzilla中的DIP1000问题

Walter已开始着手减少BugzillaDIP1000错误数.其中一些与需要清理的foreach循环和闭包有关.
一个默认进入DIP1000问题是如何处理引用 中 域歧义.Walter实现了半修复.已合并了一些PR,但其他一些停滞不前的PR阻碍了DIP1000,他想让那些动起来.

安德烈
Andrei在电子邮件中讨论.

他先说,反射内置位域很奇怪,你拥有小于8位的东西,且无法使用指针.有关位域的提议都必须考虑到该点.Walter__traits(getMembers)返回聚集的只是故事的一半.gettersetter呢?库解决方案有这些,但对内置,它们是编译器神奇.

为了处理getter/setter,Walter认为有新的trait可查询给定的成员是否是位域或其他,但他还未解决.另一种选择是编译器可"装配"getter/setter.

Andrei认为,必须权衡仅针对位域特殊壳反射的成本与"已经在ImportC中拥有它们,在D中启用它们"的便利性.他说,反射位域是严重负担.

Iain位域是否真的是问题?为什么不有n位类型?Andrei回应说D曾经有位类型,但正是因为内置位域附带负担,它被删除了.
Ali认为应该使库位域语法类似C位域语法.马丁认为意义不大.getMembers仍然返回模板实例而不是字段.
Martin指出,位域优于库实现Iainn位类型,因为可为每个单独位域成员加注释.

Walter指出,使用库位域静初化器来说是有问题的.Andrei说这是有效观点,但它可在库代码中解决.

Mathias建议当前实现在定义字段时,用了错误的方法来匹配C中用位字段方式.他认为相反,应该只按字节对齐定义访问器.Andrei说这是有效的替代方案,可简化代码.

相关主题(使C编译器布局兼容,简化库语法,FPGA上的n位,打包布尔,标准化D位域布局,与C实现的兼容性等).太多,无法在此总结.
Andrei确实建议Walter在继续使用内置实现前,应试验库实现.
1个,1个,两个问题.


状态更新:引用 中 域歧义现已修复这里,及无效的纯域推导这里进出中推导,这里,目前,多数未解决的问题都与嵌套函数有关.Atila为域错误打印弃用消息来恢复dip1000,这里.

posted @   zjh6  阅读(22)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现
点击右上角即可分享
微信分享提示