首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

先别急着“用Rust重写”,可能没有说那么安全

,Rust 和 C 对于其中 a 和 b 分别做出了不同假设,而且从 C 调用 add_twice(&bar, &bar) 会导致未定义行为。...然而,C 和 Rust 代码联合体静默调用了未定义行为,结合具体架构、Rust 版本和 LLVM 版本,这有可能引发内存安全问题。 在实践当中,这个问题涉及人为因素,而且很难加以预防。...其实这个问题不仅困扰 Rust,FFI 是出了棘手且极易引发错误,即使 Rust 也难以将其“驯服”。...我们将本节内问题划分成以下几类:首先是内存时空安全;其次是异常问题中一类常见错误——跨 FFI 边界展开堆栈属于未定义行为,因此可能构成难以察觉严重故障;第三是类型安全和 Rust 关键不变量相关错误...其他未定义行为 还有其他一些更加“玄幻”未定义行为,主要涉及不同语言细节和架构 ABI(应用程序二进制接口)特殊约定。 胶水代码。

34130

目前CSDN上最全面的C语言讲解如何用更高层次编写嵌入式C代码

,介绍了该编译器特性、对未定义行为处理以及一些高级应用;在此基础上,介绍了防御性编程概念,提出了编程过程中就应该防范于未然多种措施;提出了测试对编写优质嵌入式程序重要作用以及常用测试方法;最后...现在出了switch语句,执行了use_modes_pointer()函数。但必要初始化工作并未完成,为将来程序失败埋下了伏笔。...C标准委员会定义未定义行为原因如下: 简化标准,并给予实现一定灵活性,比如不捕捉那些难以诊断程序错误; 编译器开发商可以通过未定义行为对语言进行扩展 C语言未定义行为,使得C极度高效灵活并且编译器实现带来了方便...但是还是有一些方法可以降低这种事件,总结如下: 了解C语言未定义行为 标准C99附录J.2“未定义行为”列举了C99中显式未定义行为,通过查看该文档,了解那些行为未定义,并在编码中时刻保持警惕;...这是一个经常会遇到事情,举一个例子,程序一个变量在运行时总是不正常被改变,那么有理由怀疑临近变量或数组溢出了,溢出数据更改了这个变量值。

2.1K21
您找到你想要的搜索结果了吗?
是的
没有找到

JS到底是怎么执行:一文彻底搞清执行上下文

在开始之前,你需要先熟悉一些概念,因为我们将在本文中经常用到它们: 解析器: 语法解析器是一个逐行读取代码程序理解代码如何符合编程语言定义语法,以及代码应该做什么。...它们通常在语句中使用,比如将函数赋值变量: let someValue = function(){ //statements } 现在,我们已经知道了这些概念,让我们开始吧。...函数提升 在大多数情况下,当构建一个应用程序时,开发人员可以选择在脚本顶部定义函数,然后在代码中调用它们,就像这样: 但是,由于提升原因,这段代码仍然可以工作。...为了理解执行堆栈工作过程,考虑下面的代码示例: var name = "Victor"; function first() { var a = "Hi!"...当JS引擎遇到first()函数调用时,会为创建一个新FEC。这个新上下文被置于当前上下文顶部,形成了所谓执行堆栈

1.3K60

37个JavaScript基本面试问题和解答(建议收藏)

(这就是为什么你应该在你代码中使用strict,一个重要例子!) 3、下面的代码将输出到控制台是什么?,为什么?...他们都会返回同样值吗?为什么或者为什么?...由于代码其余部分是完全有效,即使没有被调用或做任何事情(只是一个未使用代码块,定义了一个属性栏,等于字符串“hello”),所以不会抛出任何错误。...为什么? (b) 提供一个或多个可按预期工作替代实现。 答: (a) 无论用户点击哪个按钮,数字5将始终记录到控制台。...16、如果数组列表太大,以下递归代码将导致堆栈溢出。你如何解决这个问题,仍然保留递归模式?

2.9K10

JS 到底是在干嘛:一文搞懂JS 执行上下文

在开始之前,你需要先熟悉一些概念,因为我们将在本文中经常用到它们: 解析器: 语法解析器是一个逐行读取代码程序理解代码如何符合编程语言定义语法,以及代码应该做什么。...它们通常在语句中使用,比如将函数赋值变量: let someValue = function(){ //statements } 现在,我们已经知道了这些概念,让我们开始吧。...函数提升 在大多数情况下,当构建一个应用程序时,开发人员可以选择在脚本顶部定义函数,然后在代码中调用它们,就像这样: 但是,由于提升原因,这段代码仍然可以工作。...当JS引擎遇到first()函数调用时,会为创建一个新FEC。这个新上下文被置于当前上下文顶部,形成了所谓执行堆栈。...创建“this”对象,但是可以访问定义环境对象。通常是window对象。

29410

STM32编程:是时候深入理解栈了

FIQ FIQ_STACK 用于高速(FIQ)中断处理程序堆栈。 Undefined UND_STACK 堆栈用于未定义指令中断。 支持硬件协处理器和指令集扩展软件仿真。...Abort ABT_STACK 用于指令获取和数据访问存储器中止中断处理程序堆栈。...image-20200419163415180.png 图为什么没有将0x2000 07D8画在栈区呢?通过调试发现,这个字空间没有用做栈实际存储。...将n改为21编译运行,来看一看: stackOverflow_zhihu.gif 看到了吧,惊喜来了,栈溢出了程序已经不听话了,完全不知道在干嘛了。...总结一下 栈是一种LIFO后入先出数据结构模型,是C/C++程序运行时基础,没这个栈,C/C++玩不转 栈在嵌入式编程领域随处可见,比如C栈,中断栈、异常栈、任务栈等等,但其基本工作原理都一样。

1K00

JavaScript 编程精解 中文第三版 八、Bug 和错误

我们知道程序运行出了问题,试图找出其原因。 这是一个地方,你必须抵制随机更改代码来查看它是否变得更好冲动。 相反,要思考。 分析正在发生事情,并提出为什么可能发生理论。...然后,再做一些观察来检验这个理论 - 或者,如果你还没有理论,可以进一步观察来帮助你想出一个理论。 有目的地在程序使用console.log来查看程序当前运行状态,是一种不错获取额外信息方法。...但是如果你创建了一些将被其他人使用东西,你通常希望程序比只是崩溃做得更好。 有时候,正确做法是不择手段地继续运行。 在其他情况下,最好向用户报告出了什么问题然后放弃。...如果异常总是会将堆栈尺寸缩减到栈底,那么异常也就毫无用处了。只不过是换了一种方式来彻底破坏你程序罢了。异常真正强大地方在于你可以在堆栈上设置一个“障碍物”,当异常缩减堆栈到达这个位置时会被捕获。...这使得这种错误不太可能被忽视,并且当它们发生时更容易找到它们原因。 我建议尝试为每种可能不良输入编写断言。 这将是很多工作,并会产生非常杂乱代码。

1.2K100

Unsafe 随堂小测题解(一)

官方给出解释为: “健全性是一个类型系统概念,意味着类型系统是正确,即,类型良好程序实际上应该具有该属性。对于 Rust 来说,意味着类型良好程序不会导致未定义行为。...但是这个承诺只适用于 Safe Rust。对于 Unsafe Rust要有开发者/程序员来维护这个契约。因此,如果Safe 代码公开 API 不可能导致未定义行为,就可以说这个库是健全。...反之,如果安全代码导致未定义行为,那么这个库就是健全。 也就是说,开发者在编写 Unsafe Rust 代码时候,有义务来保证提供安全抽象接口是不会有未定义行为产生。...违反了健全性,就是健全(Unsound)未定义行为 (Undefined Behavior) 准确定义,可以参加上面提到术语指南。 在对这两个基本术语了解以后,我们就可以来解题了。...val 也是内存对齐,因为使用了引用。

89120

几个嵌入式项目中技巧!

今天大家介绍7个易操作且可以长久使用技巧,它们对于确保系统更加可靠地运行并捕获异常行为大有帮助。...如果系统出了某些差错,处理器开始执行程序空间以外代码,就会触发ISR,并在决定校正行动之前提供储存处理器、寄存器和系统状态机会。...技巧2---检查应用程序CRC对嵌入式工程师来说一个很大好处是,我们IDE和工具链可以自动产生应用程序或内存空间校验和(Checksum),从而根据这个校验和验证应用程序是否完好。...毕竟,这是一种常在计算器系统中使用技术,在计算器系统中,只有在有必要时,内存才会被分配。例如,以C开发时,工程师可能倾向于使用malloc来分配在堆(heap)上空间。...如果出现这些问题时,大多数嵌入式系统并没有 资源或知识来监视堆或妥善地处理。而当它们发生时,如果应用程序提出对空间要求,但却没有所请求空间可以使用,会发生什么事呢?

17520

C++(STL3)容器适配器(1) stack,queue and priority_queue

下面展示了如何定义一个使用 list 堆栈: std::stack> fruit; 创建堆栈时,不能在初始化列表中用对象来初始化...,但是可以用另一个容器来初始化,只要堆栈底层容器类型和这个容器类型相同。...可以用stack 实现一个简单计算器程序,如下: // A simple calculator using stack containers #include ...只能在容器末尾添加新元素,只能从头部移除元素。 许多程序使用了 queue 容器。queue 容器可以用来表示超市结账队列或服务器上等待执行数据库事务队列。...2.函数操作 queue 和 stack 有一些成员函数相似,但在一些情况下,工作方式有些不同: front():返回 queue 中第一个元素引用。

65030

你所能用到数据结构(八)

C++或者什么语言编程里面,不需要引用什么头文件就可以像声明数组一样声明一个堆栈,然后很方便就可以使用这个结构。...因为括号都是成对出现,但是在一个程序中就括号而言完全可能出现{()}这样顺序,先观察一下,发现如果括号是匹配,无论括号之间包含关系是什么,那么当出现右括号时,前一个不是对应左括号,那么一定是匹配...,那么什么也不做(当然,这里可以优化成为如果匹配直接结束),这样,最终完全匹配条件就是在程序将符号全部读完之后,堆栈是空,不然都为匹配。...第一个应用很简单,第二个应用也是每本书上都会用逆波兰表达式,为什么我还是觉得应该举这个例子呢?...让计算机在看到这个算式时候不是得出7而是得出6,再通俗一点怎样让计算机从普通计算器进化到科学计算器

60840

为什么我十分喜欢C,却很不喜欢C++?

为什么说C不是最好语言? 首先,这个世上没有最好编程语言。每种语言都有独特优势以及适用情况,所以尽管你可以在 Excel 中编写光线追踪程序,但最好还是使用其他语言。...拥有 RAII 概念:一个简单例子就是 C++ 拥有构造函数,可在创建对象时初始化对象;还拥有析构函数,在销毁对象时,做一些清理工作这个概念进一步发展,就接近 Rust 生命周期了。...当然我指的是“未定义行为”以及编译器处理方式。这已成为一大毒瘤(只要你代码依赖于二进制补码算术,就会被认定具有未定义行为,编译器会抛弃整块代码)。...例如,无法使用两个不同类型指针同时操作同一块内存区域。我无法想象为什么这种行为被禁止,其原因只可能是编译器优化。这样就不可能利用联合体将整数转换成浮点数。...总结 总的来说,我喜欢C所处中层位置,既可以完成一些底层实现,例如轻松地操作内存,同时又可以享受高级语言好处。

71210

C语言不是最好,却是我最爱~

1、为什么说C不是最好语言? 首先,这个世上没有最好编程语言。每种语言都有独特优势以及适用情况,所以尽管你可以在 Excel 中编写光线追踪程序,但最好还是使用其他语言。...拥有 RAII 概念:一个简单例子就是 C++ 拥有构造函数,可在创建对象时初始化对象;还拥有析构函数,在销毁对象时,做一些清理工作这个概念进一步发展,就接近 Rust 生命周期了。...当然我指的是“未定义行为”以及编译器处理方式。这已成为一大毒瘤(只要你代码依赖于二进制补码算术,就会被认定具有未定义行为,编译器会抛弃整块代码)。...例如,无法使用两个不同类型指针同时操作同一块内存区域。我无法想象为什么这种行为被禁止,其原因只可能是编译器优化。这样就不可能利用联合体将整数转换成浮点数。...5、总 结 总的来说,我喜欢C所处中层位置,既可以完成一些底层实现,例如轻松地操作内存,同时又可以享受高级语言好处。

11910

Reddit 观察 | 以排序为案例,对 CCPPRust 安全与性能相关性研究

即使只使用内存安全抽象来实现排序,也不能保证相邻逻辑是无未定义行为。 总体而言,性能和安全之间没有明显相关性,无论是使用安全还是不安全内部抽象。...比如导致CPU MMU异常越界读取、非法CPU指令、堆栈溢出、改变无关程序状态等等。 可能你会有疑问,排序只不过是这些数字比较和位置交换,怎么可能会产生 UB 呢?...它们析构函数将传递一个指向分配器指针以进行释放。位拷贝会导致使用后释放未定义行为,很可能以双重释放形式出现。...如果在排序完成后没有观察到这种修改,依赖于空指针检查来判断是否已经释放代码将遇到使用已释放内存未定义行为。...新、迄今为止未经测试 libc++ 实现在某些分析过安全特性上表现出了一定意识,主要是 Ord 安全性,但未能找到一种保证无未定义行为(UB)使用方式。只能执行可选越界检查。

30720

有效处理Java异常三个原则,你知道吗?

为什么出错? 在有效使用异常情况下,异常类型回答了“什么”被抛出,异常堆栈跟踪回答了“在哪“抛出,异常信息回答了“为什么“会抛出,如果你异常没有回答以上全部问题,那么可能你没有很好地使用它们。...每一种都描述了一类特定I/O错误:分别是文件丢失,异常文件结尾和错误序列化对象流.异常越具体,我们程序就能更好地回答”什么出了错”这个问题。 捕获异常时尽量明确也很重要。...举例来说:如果捕获了FileNotFoundException,它可以提示用户指定另一 个文件,某些情况下多个catch块带来额外编码工作量可能是非必要负担,但在这个例子中,额外代码的确帮助程序提供了对用户更友好响应...堆栈信息立即反映出什么出了错(提供了非法参数值),为什么出错(文件名不能为空值),以及哪里出错(readPreferences()前部分)。这样我们堆栈信息就能如实提供: ?...延迟捕获 菜鸟和高手都可能犯一个错是在程序有能力处理异常之前就捕获。Java编译器通过要求检查出异常必须被捕获或抛出而间接助长了这种行为

1.6K10

嵌入式系统常用7个技巧

大家介绍7个比较好操作且可以长久使用技巧,它们对于确保系统更加可靠地运行并捕获异常行为大有帮助 技巧1——用已知值填充ROM 软件开发人员往往都是非常乐观一群人,只要让他们代码忠实地长时间地运行就可以了...如果系统出了某些差错,处理器开始执行程序空间以外代码,就会触发ISR,并在决定校正行动之前提供储存处理器、寄存器和系统状态机会。...技巧2——检查应用程序CRC 对嵌入式工程师来说一个很大好处是,我们IDE和工具链可以自动产生应用程序或内存空间校验和(Checksum),从而根据这个校验和验证应用程序是否完好。...现在一个编程过应用程序发生改变概率是很小,但考虑每年交付数十亿个微控制器以及可能恶劣工作环境,应用程序崩溃机会并不是零。...毕竟,这是一种常在计算器系统中使用技术,在计算器系统中,只有在有必要时,内存才会被分配。例如,以C开发时,工程师可能倾向于使用malloc来分配在堆(heap)上空间。

41010

译文:开发人员面临 10个最常见JavaScript 问题

今天,JavaScript是几乎所有现代Web应用程序核心。这就是为什么JavaScript问题,以及找到导致它们错误,是Web开发人员最前沿问题。...而且,仅在实际上从未使用过replaceThing功能主体和函数中引用。 因此,我们再次想知道为什么这里存在内存泄漏。 为了理解发生了什么,我们需要更好地了解JavaScript内部工作原理。...以下是我们如何纠正JavaScript上述问题,以实现预期行为: 在这个修订后代码版本中,每次我们通过循环时都会立即执行makeHandler,每次收到i+1的当前值并将其绑定到作用域num变量。...eval()在严格模式和非严格模式下行为方式存在一些差异。最重要是,在严格模式下,在eval()语句中声明变量和函数不会在包含范围内创建。...写在最后 与任何技术一样,你越了解JavaScript为什么以及如何工作和不起作用,你代码就越可靠,你就越能有效地利用语言真正力量。

1.2K20

数据结构与算法:递归算法

重要是要知道我们应该提供某种情况来终止这个递归过程。 所以我们可以说,每次函数调用自身时都会使用原始问题简单版本。...为什么需要递归 递归是一项令人惊奇技术,借助我们可以减少代码长度并使其更易于阅读和编写。与稍后将讨论迭代技术相比,具有某些优点。...,最后,这是程序员手中一个很好工具,可以以更简单有效方式编写一些问题。...阶乘基本情况是 n = 0。当 n = 0 时,我们返回 1。 为什么递归会出现Stack Overflow错误? 如果未达到或未定义基本情况,则可能会出现堆栈溢出问题。...使用递归解决实际问题并了解其基本工作原理 问题 1: 编写一个递归关系程序来查找 n 斐波那契数列,其中 n>2 。

12910
领券