简体   繁体   中英

Inline functions in C and C++; silencing compiler warning

I have embedded C code which I'm unit testing with a C++ framework. C and C++ handle inline functions differently, so when I want to create inline functions which are used in two source files, I do this:

In a header file:

#ifdef __cplusplus
# define INLINE inline
#else
# ifndef INLINE
#  define INLINE extern inline
# endif
#endif

INLINE Uint8 my_inline_function( Uint8 stuff )
{
    return stuff;  // not really, but it's not germane to the example
}

In exactly one of the two .c files:

#define INLINE

Now both C and C++ compilers are satisfied, but when I build, I get this warning:

In file included from ../MyFile.c:28:0,
             from utest_MyFile.cpp:10:
../MyFile.h:53:0: warning: "INLINE" redefined
../MyFile.c:26:0: note: this is the location of the previous definition

Is there a way I can silence this warning?

Use #ifndef

#ifndef INLINE
# ifdef __cplusplus
#  define INLINE inline
# else
#  define INLINE extern inline
# endif
#endif

You're probably including the define multiple times in the same translation unit. You can add include guards:

#ifndef INLINE_DEFINED
#define INLINE_DEFINED

#ifdef __cplusplus
# define INLINE inline
#else
# ifndef INLINE
#  define INLINE extern inline
# endif
#endif

//...
#endif

or undefine the directive:

#undef INLINE

#ifdef __cplusplus
# define INLINE inline
#else
# ifndef INLINE
#  define INLINE extern inline
# endif
#endif

A harder approach would be to just silence the warning:

#pragma warning( disable : /*warning number*/ )

Not sure if this is cross-platform though.

First as Charles says in his comment, you shouldn't do this, C and C++ are substantially different languages. In particular their rules for inline functions are different. It will cause you pain.

Then, you have another design flaw. This is apparent since you are trying to redefine a macro. You have two different contexts for your INLINE so these represent two different things. I think the following model is much easier and direct:

  • use inline for the header files. no macro or stuff like that and no extern
  • in one C or C++ file place an "instantiation" for the same function

you should decide if your instantiation is C or C++, don't play games here. In C such an instantiation is

extern inline Uint8 my_inline_function( Uint8 stuff );

(C doesn't call that instantiation but let's just use the same term as C++)

in C++ it would be

Uint8 my_inline_function( Uint8 stuff );

That's it, no need for magic:

  • all compilation units that include the header file will have a definition available
  • for all situations where you'd still need the linker symbol the one instantiation will be used

Edit:

Seeing your comment (which doesn't convince me completely) I think you would be better off by just having one macro for the instantiation in a header file

#ifdef __cplusplus
# define INSTANT
#else
# define INSTANT extern inline
#endif

and then in one .c or .C or whatever you will need to convince the compiler

INSTANT Uint8 my_inline_function( Uint8 stuff );

I suspect that this is what causing the problem

#ifdef __cplusplus
# define INLINE inline

Try to change this to

#ifdef __cplusplus
# ifndef INLINE
# define INLINE inline
#endif

You should have the #define INLINE... in its own header file with its own header guard:

(inline.h)

#ifndef INLINE_DEFINED

#ifdef __cplusplus
# define INLINE inline
#else
# ifndef INLINE
#  define INLINE extern inline
# endif
#endif

#endif

You should then put #include "inline.h" near the top of any file that needs it.

I appreciate the advice to avoid combining C and C++, but we feel the benefits of stricter type checking and simpler-to-use unit test frameworks outweigh these hiccups. Given that, the approach I find cleanest is in the .c file replacing

#define INLINE

with

#ifndef __cplusplus
# define INLINE
#endif

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM