2501d,d作者,炮打C语言!

原文

标准C定期改进,现在为C23.但是还是没有解决一些怪东西.Dlang社区在D语言编译器中嵌入了一个C编译器,这样可编译C.

C编译器(又名ImportC)是从头开始构建的.它提供了使用现代编译器技术修复这些缺点的机会.为什么标准C不修复它们?

1,计算常式
2,编译时单元测试
3,前向引用声明
4,导入声明

计算常式

请考虑以下C代码:

int sum(int a, int b) { return a + b; }
enum E { A = 3, B = 4, C = sum(5, 6) };

gcc编译时:

gcc c test.c
test.c:3:20: error: enumerator value for C is not an integer constant
 enum E { A = 3, B, C = sum(5, 6) };
                    ^

即,虽然C可在编译时通过常量折叠计算简单式,但它不能在编译时执行函数.但ImportC可以!

C语法中出现C常式的地方,只要这些函数无I/O,访问可变全局变量,系统调用等操作,编译器就应该可在编译时执行函数.

编译时单元测试

一旦C编译器可(CTFE)编译时求值函数,突然间,其他事情就变成可能.

如,在C代码中很少看到单元测试,很明显,在构建系统单元测试需要一个单独的目标,且必须按单独的可执行文件构建和运行.

有点麻烦表明它不可能!

int sum(int a, int b) { return a + b; }
_Static_assert(sum(3, 4) == 7, "test #1");
>gcc c test.c
test.c:3:16: error: expression in static assertion is not constant
_Static_assert(sum(3, 4) == 7, "test #1");
               ^

ImportC可编译它.
这样不需要单独的构建,就可以单元测试编译时运行的函数.不需要额外的工作.每次编译代码时,都会运行单元测试.我在ImportC测试包广泛使用它.

前向声明引用

更多代码:

int floo(int a, char *s) { return dex(s, a); }
char dex(char *s, int i) { return s[i]; }
gcc c test.c
test.c:4:6: error: conflicting types for dex
 char dex(char *s, int i) { return s[i]; }
      ^

test.c:2:35:注意:前dex的隐式声明在此:

 int floo(int a, char *s) { return dex(s, a); }

如果floodex的顺序逆转,则编译正常.即编译器只知道它在词法上之前的内容.禁止前向引用.
这岂是石器时代的编译器设计?现代语言无此问题,为什么在CC++中持续存在?ImportC不是现代语言,但它是现代编译器,接受任意顺序全局声明.

为什么这很重要?一般表明每个前向定义需要一个额外的声明:

char dex(char *s, int i); //声明
int floo(int a, char *s) { return dex(s, a); }
char dex(char *s, int i) { return s[i]; } //定义

这样做,只是毫无目的的折腾.这不仅烦人,还会促使倒过来布局声明.叶函数排在最前面,全局接口函数排在最后.就像自下而上读报纸文章一样.毫无意义.
ImportC可按任意顺序编译声明.

导入声明

给定三个floo.d,dex.h,dex.c文件:

//floo.c
#include "dex.h"
int floo(int a, char *s) { return dex(s, a); }
//dex.h
char dex(char *s, int i);
//dex.c
#include "dex.h"
char dex(char *s, int i) { return s[i]; }

必须为每个外部模块制作一个.h文件是一项粗活,更差,如果.h文件与.c文件不完全匹配,你要花费大量时间找出问题所在.
答案是什么:导入dex.c!

//floo.c
__import dex;
int floo(int a, char *s) { return dexx(s, a); }
//dex.c
char dexx(char *s, int i) { return s[i]; }

甚至不必编写.h文件.当然,这也适合ImportC.
参考
导入C
D语言

:如果你在翻译单元中工作,那会大大简化,但这样可在不重复大量代码做更多的事情.我想知道作者是如何解决它的?

你是正确的,因为正在求值的函数源码必须可供编译器使用.这可通过#include来完成.我在D中就是这样,并导入包含要求代码的模块.

:如果可按宏表示测试,这是可能的,如果添加第一点,则这就很简单.
当你想要测试函数时,按宏表示测试不管用.我给出的示例很简单,很容易理解.实际使用可能更复杂.
:性能
D的编译速度C编译器快,主要是因为:
1.C预处理器是一头需要多次传递无可救药的猪.我知道,我从头开始实现了多次.C预处理器发明时是个很好的设计选择.

今天,它已变成化石.我仍对为什么C++从未来得及弃用它感到敬畏.
2.D使用导入而不是#include.这样更快,因为不需要一遍遍地编译.h文件.

D的策略是分开解析与分析语义.我想它确实慢了一点,但它也不必重新编译重复的声明折叠成一个.

当然,执行编译时函数,可能是个瓶颈,但这(当然)根据它的使用程度.喜欢轻触使用它,性能很好.如果使用它实现编译器,它可能会很慢.

我并不是建议删除C#include.导入的东西将是额外的.
:对这些问题有什么想法吗?
如果你正在使用黑客,来在C语言中用模板,则你已超越了这门语言,需要一个更强大的语言.D拥有顶级的元编程-如常,其他模板语言也在追随D的路径.
:不能使用预编译头文件?
你提到它很有趣.我在90年代为SymantecCC++实现了它们.
我再也不想这样做了!
它们很脆,是维护的噩梦.不过,它们确实加快了编译速度,但没有提供语义优势.

使用D时,我非常关注快速编译,以至于预编译的头文件无法提供足够的加速,因此值得付出痛苦.

:我个人不喜欢前向引用,因为它会使代码更难读.你不能再依赖图的拓扑顺序.
正如文章所写的,这会强制在顶部有私有叶函数,而公共接口在文件尾.可以说,正常方式是在顶部放置公共接口,而实现则在"首屏下方".

作者是D的创建者,所以他可能对D没问题.D大概是25岁.而Zig只是一个蹒跚学步的孩子.
是的.D其他语言许多最新功能源头.

我开始研究D的原因是CC++非常不愿意向前发展.
但更重要的是,Zig故意没有实现D一大堆事情.
有时需要吝啬.zig基本上是c--+,其中+常式的东西.
它会不断添加D功能,比如常式.

没人使用C++模块,因为它们使用起来很笨拙.D很容易.注意:你可以自由复制D的模块设计.这是最好的.
:C++常式
经过17年的发展,仍落后D.在D中,垃集器使得很容易分配内存.此外,只有通过函数取的路径需要与CTFE兼容,其他则不需要.
C语言:

#include <stdio.h>
void main()
{
    int i;
    for (i = 0; i < 10; ++i);
        printf("%d\n", i);
}
//99%的C程序员找不到八哥!

而等价的D语言:

import core.stdc.stdio;
void main()
{
    int i;
    for (i = 0; i < 10; ++i);
        printf("%d\n", i);
}

给你:

test.d(5): Error: use `{ }` for an empty statement, not `;`

赶紧的,标准C,修复它!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/952944.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

QT c++ 样式 设置 按钮(QPushButton)的渐变色美化

上一篇文章中描述了标签的渐变色美化,本文描述按钮的渐变色美化。 1.头文件 #ifndef WIDGET_H #define WIDGET_H #include <QWidget> //#include "CustomButton.h"#include <QVBoxLayout> #include <QLinearGradient> #include <QPushButton&…

OPT: Open Pre-trained Transformer语言模型

摘要 大规模语言模型通常需要数十万计算日的训练时间&#xff0c;展现了在零样本和小样本学习中的显著能力。鉴于其计算成本之高&#xff0c;这些模型在没有大量资本投入的情况下难以复现。对于那些通过API提供的少数模型&#xff0c;研究者无法获取完整的模型权重&#xff0c…

力扣257(关于回溯算法)二叉树的所有路径

257. 二叉树的所有路径 一.问题描述 已解答 简单 相关标签 相关企业 给你一个二叉树的根节点 root &#xff0c;按 任意顺序 &#xff0c;返回所有从根节点到叶子节点的路径。 叶子节点 是指没有子节点的节点。 示例 1&#xff1a; 输入&#xff1a;root [1,2,3,null,5…

《OpenCV计算机视觉实战项目》——银行卡号识别

文章目录 项目任务及要求项目实现思路项目实现及代码导入模块设置参数对模版图像中数字的定位处理银行卡的图像处理读取输入图像&#xff0c;预处理找到数字边框使用模版匹配&#xff0c;计算匹配得分 画出并打印结果 项目任务及要求 任务书&#xff1a; 要为某家银行设计一套…

Python学习(三)基础入门(数据类型、变量、条件判断、模式匹配、循环)

目录 一、第一个 Python 程序1.1 命令行模式、Python 交互模式1.2 Python的执行方式1.3 SyntaxError 语法错误1.4 输入和输出 二、Python 基础2.1 Python 语法2.2 数据类型1&#xff09;Number 数字2&#xff09;String 字符串3&#xff09;List 列表4&#xff09;Tuple 元组5&…

系统思考—要素连接

“改变你的思维&#xff0c;就能改变你的世界”— 诺曼皮尔 世界上的所有事物&#xff0c;都在规律的支配下&#xff0c;以系统的方式运转。显性的部分是我们能看到的“要素”&#xff0c;而那些看不见的力量&#xff0c;正是推动系统运作的要素之间的相互作用。更隐秘的&…

云原生(1)

作业&#xff1a; 1、shell 脚本写出检测 /tmp/size.log 文件如果存在显示它的内容&#xff0c;不存在则创建一个文件将创建时间写入。 2、写一个 shel1 脚本,实现批量添加 20个用户,用户名为user01-20,密码为user 后面跟5个随机字符。 3、编写个shel 脚本将/usr/local 日录下大…

【IO编程】文件IO的API

这篇文章在 文章&#xff1a;【文件I/O】文件持久化 的基础之上&#xff0c;更进一步的描述了文件IO中更多更详细的API详解。 文件IO 文件IO操作是必须要理解的环节之一&#xff0c;因为 s&#xff1a;套接字文件 &#xff1b;p: 管道文件 —> 都需要通过文件IO来进行打开…

【数据库】Unity 使用 Sqlite 数据库

1.找到需要三个 DLL Mono.Data.Sqlite.dllSystem.Data.dllsqlite3.dll 上面两个dll可在本地unity安装目录找到&#xff1a; C:\Program Files\Unity\Hub\Editor\2022.3.xxf1c1\Editor\Data\MonoBleedingEdge\lib\mono\unityjit-win32 下面dll可在sqlite官网下载到&#xff…

省级-农业科技创新(农业科技专利)数据(2010-2022年)-社科数据

省级-农业科技创新&#xff08;农业科技专利&#xff09;数据&#xff08;2010-2022年&#xff09;-社科数据https://download.csdn.net/download/paofuluolijiang/90028570 https://download.csdn.net/download/paofuluolijiang/90028570 数据 年份、省份、农业科技专利数量…

51单片机——定时器中断(重点)

STC89C5X含有3个定时器&#xff1a;定时器0、定时器1、定时器2 注意&#xff1a;51系列单片机一定有基本的2个定时器&#xff08;定时器0和定时器1&#xff09;&#xff0c;但不全有3个中断&#xff0c;需要查看芯片手册&#xff0c;通常我们使用的是基本的2个定时器&#xff…

计算机的错误计算(二百零九)

摘要 利用两个大模型判断 是否为有理数&#xff1f;其值是多少&#xff1f;由实验知&#xff0c;其中一个大模型判断错误&#xff0c;说不是有理数&#xff1b;至于其值&#xff0c;该大模型选了一个错误的数值。 例1. e^(45*ln(24.8))是有理数吗&#xff1f;其值是多少&am…

Facebook 隐私变革之路:回顾与展望

在数字时代&#xff0c;个人隐私的保护一直是社交平台面临的重大挑战之一。作为全球最大的社交网络平台&#xff0c;Facebook&#xff08;现为Meta&#xff09;在处理用户隐私方面的变革&#xff0c;历经了多次调整与完善。本文将回顾Facebook在隐私保护方面的历程&#xff0c;…

第432场周赛:跳过交替单元格的之字形遍历、机器人可以获得的最大金币数、图的最大边权的最小值、统计 K 次操作以内得到非递减子数组的数目

Q1、跳过交替单元格的之字形遍历 1、题目描述 给你一个 m x n 的二维数组 grid&#xff0c;数组由 正整数 组成。 你的任务是以 之字形 遍历 grid&#xff0c;同时跳过每个 交替 的单元格。 之字形遍历的定义如下&#xff1a; 从左上角的单元格 (0, 0) 开始。在当前行中向…

GitLab CI/CD使用runner实现自动化部署前端Vue2 后端.Net 7 Zr.Admin项目

1、查看gitlab版本 建议安装的runner版本和gitlab保持一致 2、查找runner 执行 yum list gitlab-runner --showduplicates | sort -r 找到符合gitlab版本的runner&#xff0c;我这里选择 14.9.1版本 如果执行出现找不到下载源&#xff0c;添加官方仓库 执行 curl -L &quo…

机器学习基础-机器学习的常用学习方法

目录 半监督学习的概念 规则学习的概念 基本概念 机器学习里的规则 逻辑规则 规则集 充分性与必要性 冲突消解 命题逻辑 → 命题规则 序贯覆盖 单条规则学习 剪枝优化 强化学习的概念 1. 强化学习对应了四元组 2. 强化学习的目标 强化学习常用马尔可夫决策过程…

docker安装rabbit后访问报错最佳的几种解决方案

错误通常是由于RabbitMQ的安全配置导致的&#xff0c;RabbitMQ默认配置允许的用户仅能通过localhost访问。这通常出现在RabbitMQ的guest用户上&#xff0c;guest用户默认只能从localhost登录&#xff0c;而无法从其他IP地址进行远程访问。 解决方法&#xff1a; 1. **创建一个…

26个开源Agent开发框架调研总结(2)

根据Markets & Markets的预测&#xff0c;到2030年&#xff0c;AI Agent的市场规模将从2024年的50亿美元激增至470亿美元&#xff0c;年均复合增长率为44.8%。 Gartner预计到2028年&#xff0c;至少15%的日常工作决策将由AI Agent自主完成&#xff0c;AI Agent在企业应用中…

第 32 章 - Elasticsearch 的应用场景与技术解决方案

思维导图 0. 简介 Elasticsearch 主要应用于搜索场景。场景的如 应用内的搜索框、还有日志搜索等。 下面将介绍 Elasticsearch 在开发中的常见应用场景。 1. 日志搜索 日志搜索是最常见的应用。 其组合技术为&#xff1a;Kafka、Logstash、Elasticsearch、Kibana 该组合整体…

VsCode对Arduino的开发配置

ps&#xff1a;我的情况是在对esp32进行编译、烧录时&#xff0c;找不到按钮&#xff0c;无法识别Arduino文件&#xff0c;适合已经有ini文件的情况。 1.在vscode中安装拓展 2.打开设置&#xff0c;点击右上角&#xff0c;转到settings.json文件 3.复制以下代码并保存 {"…