C99和C ++的内联函数的兼容定义 [英] Compatible definitions of inline functions for C99 and C++

查看:307
本文介绍了C99和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 ++应用程序中,我在链接时收到有关多个定义的错误。尽管 externC 标头警告说明符,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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆