C++11アプリケーションコードで使用されるC99コードのユーティリティライブラリがあります。いくつかのインライン関数は、次のように変換ユニットで明示的に生成されたコードを使用してC99スタイルで宣言されます。
// buffer.h
inline bool has_remaining(void* obj) {
...
}
// buffer.c
extern inline bool has_remaining(void * obj);
ただし、has_remaining
C ++アプリケーションで使用しようとすると、リンク時に複数の定義に関するエラーが発生します。extern "C"
ヘッダーガード指定子にもかかわらず、g++はライブラリにすでに存在するインラインコードをインスタンス化しているようです。
g ++にこのタイプの定義を強制的に使用させる方法はありますか?
#ifdef __cplusplus
属性を使用した外部定義の場合、正しいことが起こるように見えgnu_inline
ますが、最新のCヘッダーを最新のC ++と互換性を保つためのより移植性の高い方法は確かにありますか?
-編集:実例-
buffer.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 */
buffer.c:
#include "buffer.h"
extern inline bool has_remaining(void const* const obj);
app.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);
}