0

For C99, is the following syntax legal when splitting up static inline functions into separate declarations and definitions?

foo.h:

#include "foo_decl.h"
#include "foo_def.h"

foo_decl.h:

#ifndef _FOO_DECL_H
#define _FOO_DECL_H

/* Here we document foo */
inline int foo(int x);

/* Here we document bar */
inline int bar(int x, int y);

#endif // _FOO_DECL_H

foo_def.h:

#ifndef _FOO_DEF_H
#define _FOO_DEF_H

inline static int foo(int x) { return x+3; }

inline static int bar(int x, int y) { return x-y+22; }

#endif // _FOO_DEF_H

The declaration is really useless to the compiler, but it serves a purpose for collecting documentation for functions in one place without getting cluttered by interspersed implementation details.

Or should foo_decl.h include the static keyword?

Jason S
  • 184,598
  • 164
  • 608
  • 970
  • static AND inline should go in the `*.c` file, you don't need to declare a static signature outside its compilation unit, the whole point of static is that it is only available in the compilation unit of which it was compiled. – Ryan May 19 '16 at 21:07
  • 1
    @self: actually it depends on the compiler, e.g. for some versions of gcc you need `static inline` in the header, otherwise debug builds fail due to multiple definitions at link time. – Paul R May 19 '16 at 21:11
  • @self -- the intent is to place into a .h file for inclusion in multiple compilation units as per Paul R's comment. – Jason S May 19 '16 at 21:37
  • 1
    @self `static inline` in a header is the only way to have the code compatible with both ISO C and GNU C, [see here for detail](http://stackoverflow.com/a/216546/1505939) – M.M May 19 '16 at 21:52
  • `inline` definitions in a .c file are completely pointless. The only use that `inline` has is that you can put a definition in a .h file such that several translation units see it. – Jens Gustedt May 19 '16 at 22:08
  • 1
    @JensGustedt: Not really. Yo might want to document the function is a critical path. Without `static`, this is even vital to provide a callable definition for the function in the header. – too honest for this site May 19 '16 at 22:16

1 Answers1

1

This is undefined behaviour according to 6.2.2/7:

If, within a translation unit, the same identifier appears with both internal and external linkage, the behavior is undefined.

The line inline int foo(int x); declares foo to have external linkage (6.2.2/5), but static int foo(int x) { declares foo to have internal linkage.

If you really want to do this then the versions in foo_decl.h and foo_def.h must either both have static, or neither have static. In the latter case exactly one .c file must have extern inline int foo(int x);.

M.M
  • 138,810
  • 21
  • 208
  • 365