2016-04-26 124 views
1

我從源碼構建了this project。我有一個設置點擊此代碼路徑:std :: errc ABI可移植性

if (err != std::errc::no_such_file_or_directory) { 
    Ctx.Diags.diagnose(moduleID.second, diag::sema_opening_import, 
         moduleID.first, err.message()); 
    } 

在我的系統(Debian Jessie)上,此條件評估爲false。因此我們不會撥打Ctx.Diags.diagnose

但是,我把我建立的二進制文件給了一個運行Ubuntu的朋友。在他的系統中完全相同的條件下,if語句的計算結果爲true,err.message()No such file or directory

這怎麼可能?我以爲std::errc應該是便攜式?根據POSIX的要求,兩個系統上的ENOENT都是2

我認爲這與他的系統在運行時的libstd有所不同,它與構建時的系統上的libstd不同,但我不明白爲什麼,或者如何構建便攜版本。

+0

什麼是相關的GCC版本? –

+1

這種'!='比較背後有很多事情 - 最終涉及比較兩個'error_category'的身份。 GCC 5在error_category相關的東西上有一個ABI變化(因爲std :: string變化),所以它們實際上有兩個'generic_category()'和兩個'system_category()'(更新的版本是在內聯命名空間中)。如果你的代碼以某種方式設法將這兩者混合,那可以解釋這種行爲。 –

+0

未安裝GCC。該項目實際上是用clang-3.5-10(Jessie)構建的,Ubuntu機器有clang-3.6.2-1。我有* lib * gcc,libgcc-4.9.2-10,而Ubuntu系統有libgcc-5.2.1-22ubuntu2。 – Drew

回答

0

@ T.C.在上述評論中的假設是正確的。

ABI for C++ 11功能在GCC 4.9中的實驗性C++ 0x支持和GCC 5.x中完成的C++ 11支持之間發生了變化,所以如果您的代碼使用C++ 11,使用GCC 4.9進行編譯,然後使用GCC 5的libstdC++。

這是PR 66438。我將它視爲無效,因爲混合4.9和5.x不適用於C++ 11代碼。