public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* C++-compatible definitions of C99-style inline functions
@ 2013-01-18  3:28 Solomon Gibbs
  2013-01-18  5:43 ` Solomon Gibbs
  0 siblings, 1 reply; 4+ messages in thread
From: Solomon Gibbs @ 2013-01-18  3:28 UTC (permalink / raw)
  To: gcc-help

Hello,

I have some 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 using the C99 extern inline.

However, when I try to use one of the inline functions 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" specifier.

If I #ifdef __cplusplus a definition with the gnu_inline attribute,
the right thing /seems/ to happen and no symbol is generated by g++,
but I'm a bit uncomfortable with this approach; it's not portable, and
I'm not sure I understand what's happening in the C++ optimizer.

Is there a portable replacement for the gnu_inline attribute in this case?
Is g++ actually inlining any method calls when the attribute is applied?

Thanks.

Here is an example:

// buffer.h

#ifndef BUFF_H
#define BUFF_H

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

#ifdef __cplusplus
extern "C" {
#endif

#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);
}

#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 "buffer.h

int main(int argc, char** argv) {
   char const* str = "okay";
   has_remaining(str);
   return (0);
}

# Compile with gcc 4.7.2 / mingw32

$ gcc -g -O0 -std=gnu99 -o buffer.o -c buffer.c
$ g++ -g -O0 -std=gnu++11 -o app.o -c app.cpp
$ g++ -Wl,--subsystem,console -o app.exe app.o buffer.o
buffer.o: In function `has_remaining':
c:\tmp/buffer.h:17: multiple definition of `has_remaining'
app.o:c:\tmp/buffer.h:17: first defined here
collect2.exe: error: ld returned 1 exit status

^ permalink raw reply	[flat|nested] 4+ messages in thread

* C++-compatible definitions of C99-style inline functions
  2013-01-18  3:28 C++-compatible definitions of C99-style inline functions Solomon Gibbs
@ 2013-01-18  5:43 ` Solomon Gibbs
  2013-01-18  8:14   ` Marc Glisse
  0 siblings, 1 reply; 4+ messages in thread
From: Solomon Gibbs @ 2013-01-18  5:43 UTC (permalink / raw)
  To: gcc-help

Hello,

I have some 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 using the C99 extern inline.

However, when I try to use one of the inline functions 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" specifier.

If I #ifdef __cplusplus a definition with the gnu_inline attribute,
the right thing /seems/ to happen and no symbol is generated by g++,
but I'm a bit uncomfortable with this approach; it's not portable, and
I'm not sure I understand what's happening in the C++ optimizer.

Is there a portable replacement for the gnu_inline attribute in this case?
How does this affect what g++ actually optimizes?

Thanks.

Here is an example:

// buffer.h

#ifndef BUFF_H
#define BUFF_H

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

#ifdef __cplusplus
extern "C" {
#endif

#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);
}

#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 "buffer.h

int main(int argc, char** argv) {
   char const* str = "okay";
   has_remaining(str);
   return (0);
}

# Compile with gcc 4.7.2 / mingw32

$ gcc -g -O0 -std=gnu99 -o buffer.o -c buffer.c
$ g++ -g -O0 -std=gnu++11 -o app.o -c app.cpp
$ g++ -Wl,--subsystem,console -o app.exe app.o buffer.o
buffer.o: In function `has_remaining':
c:\tmp/buffer.h:17: multiple definition of `has_remaining'
app.o:c:\tmp/buffer.h:17: first defined here
collect2.exe: error: ld returned 1 exit status

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: C++-compatible definitions of C99-style inline functions
  2013-01-18  5:43 ` Solomon Gibbs
@ 2013-01-18  8:14   ` Marc Glisse
  2013-01-18 15:27     ` Solomon Gibbs
  0 siblings, 1 reply; 4+ messages in thread
From: Marc Glisse @ 2013-01-18  8:14 UTC (permalink / raw)
  To: Solomon Gibbs; +Cc: gcc-help

On Thu, 17 Jan 2013, Solomon Gibbs wrote:

> Hello,
>
> I have some 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 using the C99 extern inline.
>
> However, when I try to use one of the inline functions 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" specifier.

Your issue seems specific to windows. On linux, gcc does instantiate the 
inline code, but it emits a weak symbol in app.o that is discarded at link 
time in favor of the strong one in buffer.o.

-- 
Marc Glisse

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: C++-compatible definitions of C99-style inline functions
  2013-01-18  8:14   ` Marc Glisse
@ 2013-01-18 15:27     ` Solomon Gibbs
  0 siblings, 0 replies; 4+ messages in thread
From: Solomon Gibbs @ 2013-01-18 15:27 UTC (permalink / raw)
  To: gcc-help

On Fri, Jan 18, 2013 at 2:55 AM, Marc Glisse <marc.glisse@inria.fr> wrote:
> On Thu, 17 Jan 2013, Solomon Gibbs wrote:
>
>> Hello,
>>
>> I have some 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 using the C99 extern inline.
>>
>> However, when I try to use one of the inline functions 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" specifier.
>
>
> Your issue seems specific to windows. On linux, gcc does instantiate the
> inline code, but it emits a weak symbol in app.o that is discarded at link
> time in favor of the strong one in buffer.o.
>
>

Since this code is valid under C99 and C++11 (correct?), and it
appears that COFF support for weak symbols is under development, is
this a deficiency that's reportable via the GCC or MinGW bug trackers?

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2013-01-18 14:26 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2013-01-18  3:28 C++-compatible definitions of C99-style inline functions Solomon Gibbs
2013-01-18  5:43 ` Solomon Gibbs
2013-01-18  8:14   ` Marc Glisse
2013-01-18 15:27     ` Solomon Gibbs

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).