使用最新的 gcc 生成库并使用较旧的 gcc 来使用它 - 尽管 C++ 版本相同,但为什么还会出现问题?

2024-04-09

不要问我为什么要做我正在做的事情……那将是一个很长的故事。 目前,这篇文章的目的是学习并理解为什么事情没有按照我预期的方式进行。也许我的期望是错误的?

  • 因此,最初我使用最近的编译器从源代码构建了自己的 SystemC 2.3.3 库,例如海湾合作委员会10.2.0。但是,为了保持与旧版 gcc 的向后兼容性,我请求 C++11 :

    ./configure CXXFLAGS="-DSC_CPLUSPLUS=201103L"
    
  • 接下来,我想使用支持 C++11(和相同 ABI)的旧版 gcc 构建一个应用程序,例如海湾合作委员会8.2.0, :

    g++ -std=c++11 sc_main.cpp -I/path/to/systemc/include -L/path/to/systemc/lib -lsystemc -lm -o sim
    

令我惊讶的是,链接失败:

libsystemc.so: undefined reference to `std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream()

实际上,比较的输出

nm --demangle `/path/to/gcc/10.2.0/bin/g++ --print-file-name libstdc++.so` | grep "std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::"

and

nm --demangle `/path/to/gcc/8.2.0/bin/g++ --print-file-name libstdc++.so` | grep "std::__cxx11::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::"

揭示出一些差异。事实上,前者包含std::basic_stringstream<char, std::char_traits<char>, std::allocator<char> >::basic_stringstream()而后者则不然。

这是预期的吗?这是否意味着一般而言,这是必要的,但还不够库的生产者和使用者使用相同的 C++ 版本(和相同的 ABI)?还是还有其他我不明白的事情发生?


这是否意味着一般来说,这是必要的,但还不够? 库的生产者和使用者使用相同的 C++ 版本(以及 > 相同的 ABI)?

正确的。向后/向前兼容性不仅仅由编译源代码时使用的 C++ 语言版本定义。向后/向前兼容性本身就是一个复杂的话题。但我只会给出一个简单的例子来说明一些基本概念。

让我们简化一下std::string是。它基本上是一个指针,以及字符串中的字符数:

namespace std {

    class string {
         char *chars;
         size_t nchars;
    public:
         // Constructors and other methods.
    };
}

真实的std::string稍微复杂一些(并且会使用为 C++ 实现保留的符号名称,但这并不重要)。这只是一个简化的说明。std::string甚至在 C++11 之前就已经存在。所以,多年来,事情不断发展,您的 C++ 编译器已更新到 C++20。不管出于什么原因,它的 C++ 库决定稍微改变这个类:

namespace std {

    class string {
         size_t nchars;
         char *chars;
    public:
         // Constructors and other methods.
    };
}

此时,您可以选择指示新的 C++ 编译器仅在 C++11 语言修订版上进行编译。这将仅允许 C++11 语言功能。但是,生成的二进制代码仍然无法与旧版本 C++ 编译器构建的代码进行二进制兼容,该编译器是使用不兼容的类布局进行编译的。

一般来说:为了使新编译器构建的 C++ 代码与旧编译器构建的代码二进制兼容,需要显式编译/配置选项。这当然有可能是指定通用 C++ 语言版本的选项,但仅仅这样做通常是不够的。所做的只是指示编译器使用哪种语言版本来编译 C++ 代码。较新的语言版本废弃/弃用了早期版本的功能,并且语言选项的目的是允许为早期版本的 C++ 标准编写源代码来编译,由currentC++编译器。这与向后/向前兼容性不同。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用最新的 gcc 生成库并使用较旧的 gcc 来使用它 - 尽管 C++ 版本相同,但为什么还会出现问题? 的相关文章

  • Qt - 无法让 lambda 工作[重复]

    这个问题在这里已经有答案了 我有以下功能 我想在其中修剪我的std set
  • Linux TUN/TAP:无法从 TAP 设备读回数据

    问题是关于如何正确配置想要使用 Tun Tap 模块的 Linux 主机 My Goal 利用现有的路由软件 以下为APP1和APP2 但拦截并修改其发送和接收的所有消息 由Mediator完成 我的场景 Ubuntu 10 04 Mach
  • ASP .NET MVC,创建类似路由配置的永久链接

    我需要帮助在 MVC 网站中创建类似 URL 路由的永久链接 Slug 已设置为 www xyz com profile slug 代码为 routes MapRoute name Profile url profile slug defa
  • try-catch 中未处理的异常

    try list from XElement e in d Descendants wix File where e Attribute Name Value Contains temp Name e Parent Parent Attri
  • 在 Xcode4 中使用 Boost

    有人设置 C Xcode4 项目来使用 Boost 吗 对于一个简单的 C 控制台应用程序 我需要在 Xcode 中设置哪些设置 Thanks 用这个来管理它 和这个
  • TextBox 焦点的 WinForms 事件?

    我想添加一个偶数TextBox当它有焦点时 我知道我可以用一个简单的方法来做到这一点textbox1 Focus并检查布尔值 但我不想那样做 我想这样做 this tGID Focus new System EventHandler thi
  • 获取从属性构造函数内部应用到哪个属性的成员?

    我有一个自定义属性 在自定义属性的构造函数内 我想将属性的属性值设置为属性所应用到的属性的类型 是否有某种方式可以访问该属性所应用到的成员从我的属性类内部 可以从 NET 4 5 using CallerMemberName Somethi
  • 如何在 VS 中键入时显示方法的完整文档?

    标题非常具有描述性 是否有任何扩展可以让我看到我正在输入的方法的完整文档 我想查看文档 因为我可以在对象浏览器中看到它 其中包含参数的描述和所有内容 而不仅仅是一些 摘要 当然可以选择查看所有覆盖 它可能是智能感知的一部分 或者我不知道它并
  • 禁用 LINQ 上下文的所有延迟加载或强制预先加载

    我有一个文档生成器 目前包含约 200 个项目的查询 但完成后可能会超过 500 个 我最近注意到一些映射表示延迟加载 这给文档生成器带来了一个问题 因为它需要根据生成的文档来访问所有这些属性 虽然我知道DataLoadOptions可以指
  • 为什么 FTPWebRequest 或 WebRequest 通常不接受 /../ 路径?

    我正在尝试从 ftp Web 服务器自动执行一些上传 下载任务 当我通过客户端甚至通过 Firefox 连接到服务器时 为了访问我的目录 我必须指定如下路径 ftp ftpserver com AB00000 incoming files
  • 事件日志写入错误

    很简单 我想向事件日志写入一些内容 protected override void OnStop TODO Add code here to perform any tear down necessary to stop your serv
  • 通过不同 DLL 或 EXE 中的指针或引用访问 STL 对象时发生访问冲突

    我在使用旧版 VC6 时遇到以下问题 我只是无法切换到现代编译器 因为我正在处理遗留代码库 http support microsoft com kb 172396 http support microsoft com kb 172396
  • 如何排列表格中的项目 - MVC3 视图 (Index.cshtml)

    我想使用 ASP NET MVC3 显示特定类型食品样本中存在的不同类型维生素的含量 如何在我的视图 Index cshtml 中显示它 an example 这些是我的代码 table tr th th foreach var m in
  • 从匿名类型获取值

    我有一个方法如下 public void MyMethod object obj implement 我这样称呼它 MyMethod new myparam waoww 那么我该如何实施MyMethod 获取 myparam 值 Edit
  • 过期时自动重新填充缓存

    我当前缓存方法调用的结果 缓存代码遵循标准模式 如果存在 则使用缓存中的项目 否则计算结果 在返回之前将其缓存以供将来调用 我想保护客户端代码免受缓存未命中的影响 例如 当项目过期时 我正在考虑生成一个线程来等待缓存对象的生命周期 然后运行
  • Silverlight Datagrid:在对列进行排序时突出显示整个列

    我的 Silverlight 应用程序中有一个 DataGrid 我想在对该列进行排序时突出显示整个列 它在概念上与上一个问题类似 Silverlight DataGrid 突出显示整列 https stackoverflow com qu
  • 32位PPC rlwinm指令

    我在理解上有点困难rlwinmPPC 汇编指令 旋转左字立即然后与掩码 我正在尝试反转函数的这一部分 rlwinm r3 r3 0 28 28 我已经知道什么了r3 is r3在本例中是一个 4 字节整数 但我不确定这条指令到底是什么rlw
  • 运行代码首先迁移更新数据库时出错

    我在迁移到数据库时遇到问题 并且似乎找不到我遇到的错误的答案 System MissingMethodException Method not found System Data Entity Migrations Builders Tab
  • 在基类集合上调用派生方法

    我有一个名为 A 的抽象类 以及实现 A 的其他类 B C D E 我的派生类持有不同类型的值 我还有一个 A 对象的列表 abstract class A class B class A public int val get privat
  • WPF/数据集:如何通过 XAML 将相关表中的数据绑定到数据网格列中?

    我正在使用 WPF DataSet 连接到 SQL Server Express XAML 和 C Visual Studio 2013 Express 我从名为 BankNoteBook 的现有 SQL Server Express 数据

随机推荐