0

Let's say I have a following situation

/* module a.c */
Data secret; /* data to remain hidden */
inline int veryShortProcedure( int d ) { /* using secret */ }

/* a.h */
int veryShortProcedure( int );

/* module b.c */
#include "a.h"
int procedure( int d ) {
    /* something */
    veryShortProcedure( d );
}

The code is not correct from any C standard point of view, since whenever a procedure is inline, I cannot split it into prototype and declaration, thus I should define it in a.h.

Nevertheless the code compiles in gcc with -std=gnu90 option. My question is, what does it do then? Does gcc ignore my inline declaration? Putting the code in that way would be to my mind like wanting to inline a function on linker level, which is absurd.

What is the common practice in such case? Should I sacrifice safety or efficiency (jumping to short procedures is kinda inefficient)?

infoholic_anonymous
  • 969
  • 3
  • 12
  • 34
  • You are missing two keywords: `static` and `inline`. Please look them up in your textbook. – wildplasser Dec 01 '13 at 17:08
  • 1
    BTW, there is nothing absurd about inlining at link time: http://stackoverflow.com/questions/5987020/can-the-linker-inline-functions – NPE Dec 01 '13 at 17:09
  • I think you're barking up the wrong tree if your worried about calling short functions being your bottleneck. The compiler is more than capable of inlining. – daniel gratzer Dec 01 '13 at 17:10
  • But it kind of worries me that only gnu90 allows for such code. It makes me think it might not work as I think it does. – infoholic_anonymous Dec 01 '13 at 17:19
  • @wildplasser but if I stick to c99 rules of inlining, ie if I merge a.c to a.h, making secret static will get me nowhere. It will be visible in b.c, which is what I do not want in the first place. – infoholic_anonymous Dec 01 '13 at 17:21

2 Answers2

0

Your code is correct C99 (and C11) but it does perhaps different things than you think.

A compilation unit that sees an inline declaration and a non-inline one must emit the symbol in the produced object. The normal usage is

  • inline definition (which also serves as declaration) in a header file. Thereby the definition is visible in every compilation unit and might be used by the compiler (or not) at any point that he sees fit.
  • a non-inline declaration in one compilation unit that serves to emit the symbol in that compilation unit exactly once

With your code you'd probably have a surprise, once you'd use that .h from several compilation units. You'll have duplicate symbols when linking.

Also your declaration of secret is not as it should be. The form that you have chosen is a tentative definition and might have the same problem, namely leading to multiply defined symbols.

Put your non-inline declaration into the .c file, prefix the declaration of secret with extern and everything would be as it should be.

Jens Gustedt
  • 76,821
  • 6
  • 102
  • 177
0

Nevertheless the code compiles in gcc with -std=gnu90 option. My question is, what does it do then? Does gcc ignore my inline declaration?

See An Inline Function is As Fast As a Macro:

GCC implements three different semantics of declaring a function inline.

This is specific to GNU C90 inlining:

When an inline function is not static, then the compiler must assume that there may be calls from other source files; since a global symbol can be defined only once in any program, the function must not be defined in the other source files, so the calls therein cannot be integrated. Therefore, a non-static inline function is always compiled on its own in the usual fashion.

See also Options Controlling C Dialect: -fgnu89-inline.


What is the common practice in such case?

The common practice in my opinion should be to not use a "standard" from a quarter of a century ago, but at the very least -std=c99.

Armali
  • 18,255
  • 14
  • 57
  • 171