2016-04-26 125 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代码。