gcc 流量控制、优化

d7v8vwbk  于 2023-10-19  发布在  其他
关注(0)|答案(2)|浏览(193)

我在gcc中滥用异常作为流控制,有没有办法让它发出一些优化的代码?

  1. shiny f(legacy const &l)
  2. try
  3. {
  4. auto convert_i = [](int i) -> int
  5. {
  6. switch(i)
  7. {
  8. case 1: return 5;
  9. case 2: return 9;
  10. default: throw 0;
  11. }
  12. };
  13. return shiny
  14. {
  15. .i = convert_i(l.i)
  16. };
  17. }
  18. catch(int)
  19. {
  20. return shiny { .invalid = true };
  21. }

所以我有很多异常,这些都是在填充一个结构体时使用的,几乎所有这些都可能失败,所以写这些没有异常的代码将是一个冗长的混乱。同时,异常永远不会离开当前函数,编译器生成异常处理代码的唯一原因就是给予调试器干预的机会。
这个项目使用gcc作为编译器,并且不太可能改变。生成的代码使用大量的空间来构造,抛出,捕获和忽略异常对象,这可以避免吗?

iq3niunx

iq3niunx1#

将您的代码更改为使用std::optional将能够完全删除异常路径。有几种方法可以做到这一点,但是代码的一个相当直接的翻译可能看起来像这样:

  1. shiny f(legacy const &l)
  2. {
  3. auto convert_i = [](int i) -> std::optional<int>
  4. {
  5. switch (i)
  6. {
  7. case 1:
  8. return 5;
  9. case 2:
  10. return 9;
  11. default:
  12. return {};
  13. }
  14. };
  15. auto c = convert_i(l.i);
  16. if (c)
  17. return shiny{.i = c.value()};
  18. else
  19. return shiny{.invalid = true};
  20. }
展开查看全部
vxqlmq5t

vxqlmq5t2#

我想对你问题的前提提出质疑。你说 “所以写这段没有异常的代码将是一个冗长的混乱”.但这是真的吗那么,以下几点呢?
除此之外:我大胆猜测,所有这些本地的数据也会导致大量的开销。为什么不把它们变成带输出参数bool &conversion_failed的静态函数呢?不需要捕获局部变量和生成临时函数指针(除非它们被gcc优化掉)。

  1. shiny f(legacy const &l)
  2. {
  3. bool conversion_failed = false;
  4. auto convert_i = [&conversion_failed](int i) -> int
  5. {
  6. // Feel free to omit this line if you can accept that all conversions are run even after any one failed.
  7. if (conversion_failed) return 0; // or any nonsense value
  8. switch(i)
  9. {
  10. case 1: return 5;
  11. case 2: return 9;
  12. default: conversion_failed = true;
  13. return 0; // or any nonsense value
  14. }
  15. }
  16. shiny result {
  17. .i = convert_i(l.i),
  18. // etc...
  19. };
  20. result.invalid = conversion_failed;
  21. return result;
  22. }
展开查看全部

相关问题