在下面的代碼中,函數foo
遞歸調用一次。內部調用會導致訪問衝突。外部調用捕獲異常。__finally應該在EXCEPTION_CONTINUE_SEARCH之後運行?
#include <windows.h>
#include <stdio.h>
void foo(int cont)
{
__try
{
__try
{
__try
{
if (!cont)
*(int *)0 = 0;
foo(cont - 1);
}
__finally
{
printf("inner finally %d\n", cont);
}
}
__except (!cont? EXCEPTION_CONTINUE_SEARCH: EXCEPTION_EXECUTE_HANDLER)
{
printf("except %d\n", cont);
}
}
__finally
{
printf("outer finally %d\n", cont);
}
}
int main()
{
__try
{
foo(1);
}
__except (EXCEPTION_EXECUTE_HANDLER)
{
printf("main\n");
}
return 0;
}
這裏的預期輸出應該是
inner finally 0
outer finally 0
inner finally 1
except 1
outer finally 1
然而,outer finally 0
顯眼地從實際輸出失蹤。這是一個錯誤還是有一些我忽略的細節?
爲了完整起見,VS2015發生了,編譯爲x64。令人驚訝的是,它不會發生在x86上,導致我相信它確實是一個錯誤。
這可能在技術上屬於未定義行爲的範圍,因爲您正在分配給空指針。你有沒有嘗試用'RaiseException'拋出一個常規異常? – OmnipotentEntity
嗯,不好。這不是一個新問題,VS2013的行爲方式是一樣的。看起來像/ SAFESEH對我的結構性限制,具體到遞歸,它在非遞歸的情況下工作正常。相當可疑的任何人都可以解決這個問題,最好能ping通connect.microsoft.com。 –
@OmnipotentEntity:就C++語言標準而言,分配一個空指針是* undefined behavior *。然而,在Windows平臺上,這是明確定義的:該指令引發訪問衝突,通過SEH異常傳遞給用戶代碼。 – IInspectable