性能受到C++风格的影响?

Tre*_*ith 58 c++ performance casting

我是C++样式转换的新手,我担心使用C++样式转换会破坏我的应用程序的性能,因为我的中断服务例程中有一个实时关键的截止日期.

我听说有些演员甚至会抛出异常!

我想使用C++样式转换,因为它会使我的代码更"强大".但是,如果有任何性能损失,那么我可能不会使用C++样式转换,而是会花更多时间测试使用C风格转换的代码.


有没有人做过任何严格的测试/分析来比较C++风格的演员阵容和C风格演员阵容的表现?

你有什么结果?

你得出了什么结论?

小智 85

如果C++样式转换可以概念性地替换为C样式转换,那么就没有开销.如果不能,如同dynamic_cast没有C等价物,则必须以这种或那种方式支付费用.

例如,以下代码:

int x;
float f = 123.456;

x = (int) f;
x = static_cast<int>(f);
Run Code Online (Sandbox Code Playgroud)

使用VC++为两个强制转换生成相同的代码 - 代码是:

00401041   fld         dword ptr [ebp-8]
00401044   call        __ftol (0040110c)
00401049   mov         dword ptr [ebp-4],eax
Run Code Online (Sandbox Code Playgroud)

可以抛出的唯一C++ dynamic_cast强制转换是在转换为引用时.为避免这种情况,请转换为指针,如果转换失败,将返回0.

  • 但汇编列表......汇编列表!!! 他想要什么,*血*?:) (21认同)
  • C++样式转换永远不会被C风格的转换替换.如果有的话,那就是另一种方式.该标准仅指定C++样式转换的行为.C风格的C语言用C++语言描述. (3认同)
  • 是的,但如果 OP 接受它,可能值得 110% 清楚。;) (2认同)

Dan*_*ker 41

唯一一个在运行时具有任何额外成本的dynamic_cast,具有无法直接使用C样式转换的功能.所以你没有问题.

确保自己放心的最简单方法是指示编译器生成汇编程序输出,并检查它生成的代码.例如,在任何一个明智地实现的编译器中,reinterpret_cast将完全消失,因为它只是意味着"盲目前进并假装数据属于这种类型".


jal*_*alf 17

为什么会出现性能损失?它们执行与C强制转换完全相同的功能.唯一的区别是它们在编译时捕获了更多错误,并且在源代码中更容易搜索.

static_cast<float>(3)完全相同(float)3,并将生成完全相同的代码.

给定a float f = 42.0f reinterpret_cast<int*>(&f)完全相当于(int*)&f,并将生成完全相同的代码.

等等.唯一不同的演员是dynamic_cast,是的,可以抛出异常.但那是因为它做了C风格演员无法做到的事情.所以dynamic_cast除非你需要它的功能,否则不要使用.

假设编译器编写者是智能的通常是安全的.根据标准给出两个具有相同语义的不同表达式,通常可以安全地假设它们将在编译器中以相同的方式实现.

糟糕:第二个例子当然应该是reinterpret_cast,而不是dynamic_cast.现在修好了.

好的,只是为了说清楚,这就是C++标准所说的:

§5.4.5:

由...执行的转换

  • a const_cast(5.2.11)
  • a static_cast(5.2.9)
  • 一个static_cast跟着一个const_cast
  • a reinterpret_cast(5.2.10),或
  • 一个reinterpret_cast跟着一个const_cast.

可以使用显式类型转换的强制转换表示法执行.适用相同的语义限制和行为.如果转换可以用上面列出的多种方式解释,则使用列表中首先出现的解释,即使由该解释产生的转换是格式错误的.

因此,如果有的话,因为C风格的演员表是根据C++演员表实现的,C风格的演员表应该更慢.(当然它们不是,因为编译器在任何情况下都会生成相同的代码,但它比C++风格的转换更慢更合理.)

  • +1.哈哈5.4.5是我读到这个问题时首先想到的:D (3认同)
  • @litb - 不确定是否感到印象深刻或受到惊吓. (3认同)

Max*_*ert 15

有四种C++样式转换:

  • const_cast
  • static_cast
  • reinterpret_cast
  • dynamic_cast

如前所述,前三个是编译时操作.使用它们没有运行时间的惩罚.它们是编译器的消息,已经声明为一种方式的数据需要以不同的方式访问."我说这是一个int*,但让我访问它,好像它char*指向sizeof(int) chars"或"我说这个数据是只读的,现在我需要将它传递给一个不会修改它的函数,但是不会将参数作为const引用."

除了通过强制转换为错误类型的数据损坏以及对数据进行处理(使用C样式强制转换的可能性),这些强制转换的最常见运行时问题是实际声明的数据const可能无法转换为非const.将声明的内容const转换为非const然后修改它是未定义的. 未定义意味着你甚至不能保证会崩溃.

dynamic_cast 是一个运行时构造,必须有一个运行时成本.

这些演员阵容的价值在于他们具体说出你想要演绎的内容,从视觉上突出,并且可以通过脑死亡工具进行搜索.我建议使用它们而不是使用C风格的演员表.

  • 实际上,`static_cast`也可以导致运行时操作,就像c风格的转换一样(例如,当你从浮点转换为整数,反之亦然). (2认同)