Lig*_*ica 5 c++ exception visual-studio visual-studio-2019
当我将Visual Studio 2019从/EHsc(仅限结构化和C ++例外)切换到/EHs(也不要假设extern "C"函数不会抛出– ref)时,我试图调查生成的代码的差异,但是我似乎无法哄骗VS当我最小化它时提供一个有用的测试用例。
我很惊讶以下内容没有做到这一点(两种情况下的程序集都是相同的),因为fptr优化器不知道所引用的函数的内容(可能的定义包含在说明中)。
void foo();
/*void foo()
{
throw 0;
}*/
extern "C"
void bar(void (*fptr)())
{
fptr();
}
int main()
{
try
{
bar(&foo);
}
catch (...) {}
}
Run Code Online (Sandbox Code Playgroud)
当然,它知道任何假定的异常都会被立即捕获,并且由于/EHsc该异常的传播结果对于Microsoft而言是“未定义的”,因此它的“出现”当然是有效的结果。但这对我没有太大帮助!
那么,如何在不引入不同翻译单元的情况下执行此实验?理想情况下,我希望能够为此提供一个Compiler Explorer片段。
我的目标是证明extern "C"以良好定义的方式允许抛出(或传播)C ++异常不会比我在交易中接受的运行时成本高。
下面的MCVE可能会给你一些关于测试框架的想法。您可以轻松添加更多“彻底”的测试代码,但这将编译并运行。请注意,/EHsc设置该选项后,会生成此警告:
警告 C5039:“FuncTst”:指向传递给 -EHc 下的 extern C 函数的潜在抛出函数的指针或引用。如果此函数引发异常,则可能会发生未定义的行为。
然而,当使用时/EHs警告消失 - 这表明至少有可能生成不同的代码。
这是建议的代码:
#pragma warning(disable:4514) // These two lines de-fluff the hundreds of other
#pragma warning(disable:4710) // warning generated when /Wall is used.
#include <iostream>
using pFunc = int(__stdcall*)(int);
extern int __stdcall FuncOne(int p) {
int answer = 0;
for (int i = 0; i < p; ++i) answer += i / p; // Possible divide-by-zero
return answer;
}
extern "C" int __stdcall FuncTst(int i, pFunc fnc) noexcept // Expects noexcept but "FuncOne" can throw!
{
return fnc(i);
}
int main()
{
int q;
std::cout << "Enter test number: ";
std::cin >> q;
int z = FuncTst(q, FuncOne);
std::cout << "Result = " << z << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
希望能帮助到你!请随意提出批评和/或要求任何“改进”或解释。
注意:虽然在使用(例如)进行编译时无法专门启用警告,但您可以强制将其标记为错误(尽管这可能有点苛刻),方法是:C5039\W4
#pragma warning(error:5039)
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
66 次 |
| 最近记录: |