C99和C ++的内联函数的兼容定义 [英] Compatible definitions of inline functions for C99 and C++
问题描述
我有一个由C ++ 11应用程序代码使用的C99代码实用程序库。一些内联函数在C99风格中声明,代码在翻译单元中显式生成,如下所示:
// buffer.h
inline bool has_remaining(void * obj){
...
}
// buffer.c
extern inline bool has_remaining(void * obj) ;
然而,当我尝试使用 has_remaining
在C ++应用程序中,我在链接时收到有关多个定义的错误。尽管标头警告说明符,g ++似乎在实例化库中已存在的内联代码。
有没有办法强制g ++使用这种类型的定义?
它看起来像是 #ifdef __cplusplus
一个外部定义, gnu_inline code>属性,正确的事情会发生,但是肯定有一种更便捷的方式来保持现代C头文件与现代C ++兼容?
buffer.h:
#ifndef BUFF_H
#define BUFF_H
#include< stdbool.h>
#include< stddef.h>
#ifdef __cplusplus
externC{
#endif
inline bool has_remaining(void const * const obj){
return (obj!= NULL);
}
#ifdef __cplusplus
}
#endif
#endif / * BUFF_H * /
buffer.c:
# includebuffer.h
extern inline bool has_remaining(void const * const obj);
app.cpp:
#include
#include< stdio.h>
#includebuffer.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, - 子系统,控制台-o app.exe app.o buffer.o
buffer.o:buffer.c :( .text + 0x0):多重定义`has_remaining'
app.o:app.cpp :(。text $ has_remaining [_has_remaining] + 0x0):此处首先定义
collect2.exe:错误:ld返回1退出状态
- 编辑2 -
__ gnu_inline __
属性确实解决了多个定义的问题。我仍然希望看到一个(更多)便携式方法或一些确凿的推理,为什么不存在。
#if定义(__ cplusplus)&& define(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);
}
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没有任何经验,所以我不能说出那里发生了什么。
I have a utility library of C99 code used by C++11 application code. A few inline functions are declared in the C99 style with code explicitly generated in the translation unit like:
// buffer.h
inline bool has_remaining(void* obj) {
...
}
// buffer.c
extern inline bool has_remaining(void * obj);
However, when I try to use has_remaining
in the C++ application, I get errors about multiple definitions at link time. It seems that g++ is instantiating the inline code that already exists in the library, despite the extern "C"
header guards specifier.
Is there a way to coerce g++ into working with this type of definition?
It looks like if I #ifdef __cplusplus
an extern definition with the gnu_inline
attribute, the right thing will happen, but surely there is a more portable way to keep modern C headers compatible with modern C++?
-- Edit: Working Example --
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);
}
compile:
$ 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
--Edit 2--
The __gnu_inline__
attribute does indeed fix the problem of multiple definitions. I'd still like to see a (more) portable approach or some conclusive reasoning why one doesn't exist.
#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);
}
This was reported to gcc: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56066 after a discussion starting here: http://gcc.gnu.org/ml/gcc-help/2013-01/msg00152.html
On linux, gcc emits weak symbols for the inline functions, and a strong symbol for the extern inline one. At link time, the weak ones are discarded in favor of the strong one. Apparently, on windows, things are handled differently. I don't have any experience with windows, so I can't tell what happens there.
这篇关于C99和C ++的内联函数的兼容定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!