c++ - C99 和 C++ 的内联函数的兼容定义

标签 c++ c gcc c++11 c99

我有一个由 C++11 应用程序代码使用的 C99 代码实用程序库。一些内联函数以 C99 风格声明,并在翻译单元中显式生成代码,例如:

// buffer.h
inline bool has_remaining(void* obj) {
...
}

// buffer.c
extern inline bool has_remaining(void * obj);

但是,当我尝试在 C++ 应用程序中使用 has_remaining 时,我在链接时收到有关多个定义的错误。尽管有 extern "C" header guards 说明符,g++ 似乎正在实例化库中已经存在的内联代码。

有没有办法强制 g++ 使用这种类型的定义?

看起来如果我 #ifdef __cplusplus 一个带有 gnu_inline 属性的外部定义,正确的事情将会发生,但肯定有一种更便携的方式来保持现代C 头文件与现代 C++ 兼容?

-- 编辑:工作示例 --

缓冲区.h:

#ifndef BUFF_H
#define BUFF_H

#include <stdbool.h>
#include <stddef.h>

#ifdef __cplusplus
extern "C" {
#endif

inline bool has_remaining(void const* const obj) {
    return (obj != NULL);
}

#ifdef __cplusplus
}
#endif

#endif /* BUFF_H */

缓冲区.c:

#include "buffer.h"

extern inline bool has_remaining(void const* const obj);

应用程序.cpp:

#include <stdlib.h>
#include <stdio.h>

#include "buffer.h"

int main(int argc, char** argv) {
  char const* str = "okay";
  printf(str);

  has_remaining(str);

  return (0);
}

编译:

$ gcc -std=gnu99 -o buffer.o -c buffer.c
$ g++ -std=gnu++11 -o app.o -c app.cpp
$ g++ -Wl,--subsystem,console -o app.exe app.o buffer.o

buffer.o:buffer.c:(.text+0x0): multiple definition of `has_remaining'
app.o:app.cpp:(.text$has_remaining[_has_remaining]+0x0): first defined here
collect2.exe: error: ld returned 1 exit status

--编辑2-- __gnu_inline__ 属性确实解决了多重定义的问题。我仍然希望看到一种(更多)可移植的方法或一些不存在的结论性推理。

#if defined(__cplusplus) && defined(NOTBROKEN)
#define EXTERN_INLINE extern inline __attribute__((__gnu_inline__))
#else
#define EXTERN_INLINE inline
#endif

EXTERN_INLINE bool has_remaining(void const* const obj) {
  return (obj != NULL);
}

最佳答案

这是向 gcc 报告的: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56066 从这里开始讨论后: http://gcc.gnu.org/ml/gcc-help/2013-01/msg00152.html

在 linux 上,gcc 为内联函数发出弱符号,为 extern 内联函数发出强符号。在链接时,弱者被丢弃以支持强者。显然,在 Windows 上,事情的处理方式不同。我没有任何使用 Windows 的经验,所以我不知道那里发生了什么。

关于c++ - C99 和 C++ 的内联函数的兼容定义,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14372185/

相关文章:

c++ - SIMD:翻转四个压缩整数的符号

C++ 简单的刽子手游戏

c++ - 我可以使用 `this` 关键字从对象自身的成员函数更新对象吗?

c - waitpid 是否为已经退出的子进程生成有效的状态信息?

c++ - 如何在 Fedora 上安装 ImageMagick 开发库?

c++ - Eclipse CDT 控制台输出未显示在带有路径的调试中,也未显示在没有路径的运行中

编译时测试函数是否被优化

c++ - 如何在 mysql++ 中使用 select 将表的值传递给 c++ 的变量

c - 10的幂

c - 如何将文件中的逗号分隔行拆分为 C 中的变量?