简体   繁体   English

只能使用(稳定)第三方库使我的代码无法正常工作

[英]Can merely using (stable) third party library render my code not working

Say I have C++ project which has been working for years well. 假设我有一个C ++项目,该项目已经运行了好几年。 Say also this project might (need to verify) contain undefined behaviour. 还说这个项目可能 (需要验证)包含未定义的行为。 So maybe compiler was kind to us and doesn't make program misbehave even though there is UB. 因此,也许编译器对我们很友善,即使存在UB,也不会使程序出现异常。 Now imagine I want to add some features to the project. 现在想象我要向项目中添加一些功能。 eg add Crypto ++ library to it. 例如,向其中添加Crypto ++库。 But the actual code I add to it say from Crypto++ is legitimate. 但是我添加到Crypto ++的实际代码是合法的。 Here I read: 在这里我读到:

Your code, if part of a larger project, could conditionally call some 3rd party code (say, a shell extension that previews an image type in a file open dialog) that changes the state of some flags (floating point precision, locale, integer overflow flags, division by zero behavior, etc). 您的代码(如果属于较大项目的一部分)可以有条件地调用某些第三方代码(例如,在文件打开对话框中预览图像类型的Shell扩展),从而更改某些标志的状态(浮点精度,语言环境,整数溢出)标志,除以零行为等)。 Your code, which worked fine before, now exhibits completely different behavior. 您的代码以前运行良好,现在表现出完全不同的行为。

But I can't gauge exactly what author means. 但是我无法确切地确定作者的意思。 Does he say even by adding say Crypto ++ library to my project, despite the code from Crypto++ I add is legitimate, my project can suddenly start working incorrectly? 他是否说即使在我的项目中添加了说Crypto ++库,尽管我添加的Crypto ++代码是合法的,我的项目也会突然开始无法正常工作?

Is this realistic? 这是现实的吗? Any links which can confirm this? 任何链接可以确认这一点?

It is hard for me to explain to people involved that just adding library might increase risks. 我很难向相关人员解释说, 添加库可能会增加风险。 Maybe someone can help me formulate how to explain this? 也许有人可以帮助我制定如何解释这一点?

When source code invokes undefined behaviour, it means that the standard gives no guarantee on what could happen. 当源代码调用未定义的行为时,这意味着该标准无法保证会发生什么。 It can work perfectly in one compilation run, but simply compiling it again with a newer version of the compiler or of a library could make it break. 它可以在一次编译运行中完美运行,但是仅使用较新版本的编译器或库再次对其进行编译,可能会使其中断。 Or changing the optimisation level on the compiler can have same effect. 或者在编译器上更改优化级别可以具有相同的效果。

A common example for that is reading one element past end of an array. 一个常见的示例是读取数组末尾的一个元素。 Suppose you expect it to be null and by chance next memory location contains a 0 on normal conditions (say it is an error flag). 假设您期望它为null,并且在正常情况下,下一个内存位置偶然包含0(例如,这是一个错误标志)。 It will work without problem. 它将毫无问题地工作。 But suppose now that on another compilation run after changing something totally unrelated, the memory organization is slightly changed and next memory location after the array is no longer that flag (that kept a constant value) but a variable taking other values. 但是,现在假设在更改完全不相关的内容后再次运行编译时,内存组织稍有更改,数组之后的下一个内存位置不再是该标志(保持恒定值),而是一个采用其他值的变量。 You program will break and will be hard to debug, because if that variable is used as a pointer, you could overwrite memory on random places. 您的程序将中断并且将很难调试,因为如果将该变量用作指针,则可能会在随机位置覆盖内存。

TL/DR: If one version works but you suspect UB in it, the only correct way is to consistently remove all possible UB from the code before any change. TL / DR:如果一个版本可用,但您怀疑其中有UB,则唯一正确的方法是在进行任何更改之前,从代码中始终删除所有可能的UB。 Alternatively, you can keep the working version untouched, but beware, you could have to change it later... 另外,您可以保持工作版本不变,但是请注意,稍后可能需要更改它。

Over the years, C has mutated into a weird hybrid of a low-level language and a high-level language, where code provides a low-level description of a way of performing a task, and modern compilers then try to convert that into a high-level description of what the task is and then implement efficient code to perform that task (possibly in a way very different from what was specified). 多年以来,C已转变为低级语言和高级语言的怪异混合体,其中代码提供了执行任务方式的低级描述,现代编译器随后尝试将其转换为对任务是什么的高级描述,然后实施高效的代码来执行该任务(可能与所指定的方式完全不同)。 In order to facilitate the translation from the low-level sequence of steps into the higher-level description of the operations being performed, the compiler needs to make certain assumptions about the conditions under which those low-level steps will be performed. 为了促进从低级步骤序列转换为正在执行的操作的高级描述,编译器需要对执行这些低级步骤的条件做出某些假设。 If those assumptions do not hold, the compiler may generate code which malfunctions in very weird and bizarre ways. 如果这些假设不成立,则编译器可能会生成以非常奇怪和怪异的方式发生故障的代码。

Complicating the situation is the fact that there are many common programming constructs which might be legal if certain parts of the rules were a little better thought-out, but which as the rules are written would authorize compilers to do anything they want. 使情况复杂化的事实是,存在许多常见的编程结构,如果对规则的某些部分进行了深思熟虑,这些结构可能是合法的,但是在编写规则时,它们将授权编译器执行他们想要的任何事情。 Identifying all the places where code does things which arguably should be legal, and which have historically worked correctly 99.999% of the time, but might break for arbitrary reasons can be very difficult. 要确定所有代码执行可能合法的地方,并且历史上一直在99.999%的时间内正常工作,但是可能由于任意原因而中断,这是非常困难的。

Thus, one may wish for the addition of a new library not to break anything, and most of the time one's wish might come true, but unfortunately it's very difficult to know whether any code may have lurking time bombs within it. 因此,人们可能希望添加一个新的库而不破坏任何内容,并且大多数时候人们的愿望都可以实现,但是不幸的是,要知道是否有任何代码可能潜藏着定时炸弹是非常困难的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM