Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/150.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 与其创建智能指针,为什么我们不能修改C++;编译器在编译时更好地捕获指针问题?_C++_Pointers_Compilation_Smart Pointers - Fatal编程技术网

C++ 与其创建智能指针,为什么我们不能修改C++;编译器在编译时更好地捕获指针问题?

C++ 与其创建智能指针,为什么我们不能修改C++;编译器在编译时更好地捕获指针问题?,c++,pointers,compilation,smart-pointers,C++,Pointers,Compilation,Smart Pointers,如果我们能够设计智能指针,根据作用域知道何时销毁/删除堆内存。为什么我们不能设计编译器,在堆内存超出范围时进行标记而不被删除 为什么创建智能指针更实用 我知道这不是智能指针的唯一原因和好处,但为什么这些改进不能通过修改编译器来实现呢 谢谢当您的代码足够复杂时,决定指针是否超出范围可以简化为某种等价的问题,这对于编译器来说是一个不可判定的问题。这并不是说这个问题是可以解决的,而是不可行的,而是一个决定程序是否停止的计算机程序实际上不可能存在 这种对停止问题的简化的一个简单示例是以下伪代码: All

如果我们能够设计智能指针,根据作用域知道何时销毁/删除堆内存。为什么我们不能设计编译器,在堆内存超出范围时进行标记而不被删除

为什么创建智能指针更实用

我知道这不是智能指针的唯一原因和好处,但为什么这些改进不能通过修改编译器来实现呢


谢谢

当您的代码足够复杂时,决定指针是否超出范围可以简化为某种等价的问题,这对于编译器来说是一个不可判定的问题。这并不是说这个问题是可以解决的,而是不可行的,而是一个决定程序是否停止的计算机程序实际上不可能存在

这种对停止问题的简化的一个简单示例是以下伪代码:

Allocate x;
Do arbitrary tasks using x as storage;
Print x;
Deallocate x;
Do other tasks;
当且仅当“使用x作为存储执行任意任务”停止时,
x
才会泄漏

如果再加上额外的考虑因素,比如多线程/并发执行,问题会变得更加严重

正如Nicol Bolas所提出的,还有一些方法可以隐藏编译器无法轻松检测的指针,例如,通过uintptr__t往返指针,可能会有一些双射函数将其混淆

另一方面,这在运行时要容易得多。是一种相当成熟的技术,可以在运行时看到,比如Java虚拟机


此外,编译器协助检测C++中的泄漏和其他内存问题——CLAN+++,G++包含运行时消除器,它将在运行时警告非法访问,并在关闭时泄漏。虽然当分配不可访问/不再使用但程序尚未终止时,它不会发出警告。

当代码足够复杂时,决定指针是否超出范围可以简化为某种等价的问题-对于编译器来说,这是一个无法确定的问题。这并不是说这个问题是可以解决的,而是不可行的,而是一个决定程序是否停止的计算机程序实际上不可能存在

这种对停止问题的简化的一个简单示例是以下伪代码:

Allocate x;
Do arbitrary tasks using x as storage;
Print x;
Deallocate x;
Do other tasks;
当且仅当“使用x作为存储执行任意任务”停止时,
x
才会泄漏

如果再加上额外的考虑因素,比如多线程/并发执行,问题会变得更加严重

正如Nicol Bolas所提出的,还有一些方法可以隐藏编译器无法轻松检测的指针,例如,通过uintptr__t往返指针,可能会有一些双射函数将其混淆

另一方面,这在运行时要容易得多。是一种相当成熟的技术,可以在运行时看到,比如Java虚拟机


此外,编译器协助检测C++中的泄漏和其他内存问题——CLAN+++,G++包含运行时消除器,它将在运行时警告非法访问,并在关闭时泄漏。虽然它不警告分配何时无法使用/不再使用,但是程序尚未终止。

< P>我将忽略更大的C++问题,语言中有漏洞,让您将指针隐藏在非指针式的东西内。是的,其中许多是UB,但有些API基本上需要这些Schenanigan。从实用的角度来看,这样的事情使得自动GC变得不可能。相反,我们将假设编译器有一个完美的方法来为指针插入工具来完成这项工作。因此,我将重点讨论更明显的问题:

向后兼容性和性能

让我们假设在解决C/C++互操作问题时(可以这样做:即:C++指针仍然需要相同的大小,并存储与C指针相同的信息)。即使如此,大多数人编写代码时也不会期望垃圾回收。您已经编写了几十年的代码,用于在对象创建后销毁它们

<> P>那么基于GC的C++会对这些代码做些什么呢?如果它看到指向某个对象的指针在该对象的显式释放之后仍然存在,那么应该在什么时候销毁它?当用户说要这样做时,还是当最后一个指针消失时?如果你选择前一个答案,那么你没有得到任何东西,因为你刚刚打破了GC。如果你选择后者,那么你就违反了你与用户的约定,因为用户明确地说“销毁这个对象并释放这个内存”,而你没有

因此,必须编写一个代码库,以期待GC;你不能在幕后把它交给他们

《C++》的一个常见哲学是“只为你所用的东西付费”。垃圾收集不是免费的。即使是基于生命周期范围的GC也不是免费的,尤其是
共享的种类。但是你把这个成本强加给每个人,即使他们没有要求也不需要


没有自动内存管理是C++的一个特性,而不是bug。它允许用户有权自行决定最佳的内存管理形式。

< P>我将忽略更大的C++问题,即语言中有漏洞,让您将指针隐藏在非指针式的东西内。是的,其中许多是UB,但有些API基本上需要这些Schenanigan。从实用的角度来看,这样的事情使得自动GC变得不可能。相反,我们将假设编译器有一个完美的方法来为指针插入工具来完成这项工作。因此,我将重点讨论更明显的问题:

向后兼容性和性能

让我们假设在解决C/C++互操作问题时(可以这样做:即:C++指针仍然需要相同的大小,并存储与C指针相同的信息)。即使如此,大多数人编写代码时也不会期望垃圾回收。有几十年的代码是写给des的