异常指针清理
我们都知道抛出异常指针是不好的:
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
除了静态分析工具或代码审查之外,您无法采取任何措施来防止指针捕获。 但是,如果您几乎不可能抛出
MyExceptionClass
指针,则catch(MyExceptionClass*)
块将成为死代码。为了更彻底地防止指针抛出异常,您实际上需要做更多的工作。
隐藏所有形式的operator new --
请参阅此处。
隐藏地址运算符 -- 抛出先前分配的对象的地址会带来一些与抛出堆分配的对象相同的问题。
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, acatch(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.
如果我理解正确的话,您想将不好的做法变成编译错误。
通过使异常类型不可堆分配,您已经成功地使其非法:
唉,下一部分无法按照您想要的方式完成。 没有办法使 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:
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.
听起来您希望能够将所有通过指针抛出的实例更改为通过值抛出。 你有一个可行的办法来防止指针抛出。 但是您正在寻找一种方法来防止在所有抛出更改后意外地被指针捕获。
据我所知,这无法由语言强制执行。 但是我认为一个简单的 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...不过,我通常
不确定我是否正确理解你的问题。
I usually
Not sure, though, I understand your question correctly.
就 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 theMyExceptionClass
-- or add a static assert in the default constructor and force compilation failures so that you can identify where these default-constructedMyExceptionClass
types are instantiated.One other approach I would take would be to look for '
throw new
' clauses and just fix those.