异常指针清理

发布于 2024-07-24 02:08:41 字数 383 浏览 5 评论 0原文

我们都知道抛出异常指针是不好的:

try
{
    ...
    throw new MyExceptionClass();
}
catch (MyExceptionClass* e)
{
    ...
}

您在遗留代码中清理 catch 目标的方法是什么? 我认为我可以通过将operator new设为私有来修复第一部分:

class MyExceptionClass
{
public:
    ...
private:
    void* operator new(size_t);
}

如何在编译时使捕获部分同样丑陋? 我不想让它陷入 catch (...) 领域。

We all know that throwing pointers to exception is bad:

try
{
    ...
    throw new MyExceptionClass();
}
catch (MyExceptionClass* e)
{
    ...
}

What's your approach to cleaning the catch targets up in legacy code? I figure that I can fix the first part by making operator new private:

class MyExceptionClass
{
public:
    ...
private:
    void* operator new(size_t);
}

How can I make the catch side of things equally ugly at compile-time? I don't want to just cause this to fall into the catch (...) territory.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

恰似旧人归 2024-07-31 02:08:41

除了静态分析工具或代码审查之外,您无法采取任何措施来防止指针捕获。 但是,如果您几乎不可能抛出 MyExceptionClass 指针,则 catch(MyExceptionClass*) 块将成为死代码。

为了更彻底地防止指针抛出异常,您实际上需要做更多的工作。

隐藏所有形式的operator new --
请参阅此处

隐藏地址运算符 -- 抛出先前分配的对象的地址会带来一些与抛出堆分配的对象相同的问题。

class MyExceptionClass
{
private:
    MyExceptionClass* operator&();
}

There is nothing you can do to prevent catching by pointer, aside from static analysis tools or code review. However, if you make it nearly impossible to throw a MyExceptionClass pointer, a catch(MyExceptionClass*) block will be dead code.

To more completely prevent throwing by pointer, you'll actually need to do some more work.

Hide all forms of operator new --
See here.

Hide the address-of operator -- Throwing the address of a previously allocated object carries some of the same issues of throwing a heap-allocated object.

class MyExceptionClass
{
private:
    MyExceptionClass* operator&();
}
又爬满兰若 2024-07-31 02:08:41

如果我理解正确的话,您想将不好的做法变成编译错误。

通过使异常类型不可堆分配,您已经成功地使其非法:

throw new MyExceptionClass();

唉,下一部分无法按照您想要的方式完成。 没有办法使 catch 块变得非法。 不过,如果您将堆分配 MyExceptionClass 设为非法,则无需担心 catch 块。 只会浪费空间。

如果你想强制不被指针捕获,你需要一个类似 lint 的工具。
我建议查看 EDoC++。 它是一个经过修改的 gcc 编译器,用于检查异常的正确使用。

If I understand you correctly, you want to turn a bad practice into a compilation error.

By making the exception type non-heap-allocatable, you've managed to make this illegal:

throw new MyExceptionClass();

Alas, the next part can't be done like you want it. There's no way to make the catch block illegal. Although, if you've made it illegal to heap-allocate MyExceptionClass, there's no need to worry about the catch blocks. It'll just be wasted space.

If you want to enforce not catching by a pointer, you want a lint-like tool.
I'd recommend looking at EDoC++. It's a modified gcc compiler to check for proper exception usage.

享受孤独 2024-07-31 02:08:41

听起来您希望能够将所有通过指针抛出的实例更改为通过值抛出。 你有一个可行的办法来防止指针抛出。 但是您正在寻找一种方法来防止在所有抛出更改后意外地被指针捕获。

据我所知,这无法由语言强制执行。 但是我认为一个简单的 sed 脚本来查找 /catch (.* \*/ 的实例应该足够好了......

It sounds like you want to be able to change all instances of throw by pointer to throw by value. You have a workable kludge to prevent throwing by pointer. But you are looking for a way to prevent accidentally catching by pointer once all the throws are changed.

As far as I know this is not able to be enforced by the language. But a simple sed script to look for instances of /catch (.* \*/ should be good enough I would think...

栖竹 2024-07-31 02:08:41

不过,我通常

try
{
  throw MyException();
}
catch (const MyException& e)
{
}

不确定我是否正确理解你的问题。

I usually

try
{
  throw MyException();
}
catch (const MyException& e)
{
}

Not sure, though, I understand your question correctly.

李白 2024-07-31 02:08:41

就 C++ 语言规则而言,您不能禁止指向类型的指针,这使得捕获指向它们的指针完全合法(无论多么丑陋)。 我会编写一个简单的工具来查找所有 catch(T*) 块并更改它们。

我想说将operator new设为私有可能不起作用,因为全局new运算符可能仍会被调用。 我建议遗留代码库强制破坏动态分配是更改 MyExceptionClass 构造函数的签名 - 或者在默认构造函数中添加静态断言并强制编译失败,以便您可以识别这些默认构造的 MyExceptionClass 类型的实例化位置。

我采取的另一种方法是寻找“抛出新”子句并修复它们。

As far as in C++ language rules, you can't disallow pointers to a type which makes catching pointers to them completely legal (however ugly). I would write a simple tool which would look for all the catch(T*) blocks and just change those.

I'd say making operator new private might not work because the global new operator might still be invoked. What I'd suggest for legacy code bases to force breakage of dynamic allocations would be to change the signature of the constructor of the MyExceptionClass -- or add a static assert in the default constructor and force compilation failures so that you can identify where these default-constructed MyExceptionClass types are instantiated.

One other approach I would take would be to look for 'throw new' clauses and just fix those.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文