1

I have a variant datatype using a union.

typedef union { 
    char        *string;
    int         integer; 
    ...
} vardata_t;

I have functions in variant.c that set the value. Many of these functions are trivial.

void variant_set_integer (variant_t *v, int val) { 
    assert (v->vartype == vartype_integer); 
    v->vardata.integer = val;                   
}

If I want execution to be as fast as possible and to optimize for speed, it is my understanding I should make the function static and put it in the header instead.

// variant.h
...

// Source files using this may inline via compiler optimizations
// Source files not using this will strip via compiler optimizations
static void variant_set_integer (variant_t *v, int val) { 
    assert (v->vartype == vartype_integer); 
    v->vardata.integer = val;                   
}

Is this the best and correct strategy for optimizing for speed allowing the compiler to best take advantage of situations where it determines inlining is the best solution?

NOTE: I'm trying to determine best automatic inlining practice for speed, not solve this specific example.

B. Nadolson
  • 2,988
  • 2
  • 20
  • 27
  • 1
    a) Trying to be smarter than the compiler almost never works. b) Not much code actually needs the tiny performance gain something like this could potentially give. c) Have you tried it? Wouldn't you end up with multiple definitions of variant_set_integer() in your .o files? – John3136 Sep 04 '15 at 02:17
  • As I understand it, compilers don't generally optimize across translation units (i.e. .c source files) with the possible exception of an option in recent gcc. Multiple definitions of a symbol shouldn't exist where a compiler inlined, the instructions from the function are directly incorporated. I don't want for loops and such to be slower than they should be -- I'm trying to enable the compiler to have the information available to be able to optimize for speed. As I understand it, because of the "can't cross translation units" limitation, the function needs to be in the source file. – B. Nadolson Sep 04 '15 at 02:55

2 Answers2

2

If the functions can be made static in a single file, then make them so. Making them static in a header will mean that you get compiler warnings about unused functions unless every file that includes the header also uses every one of those functions.

If you make them static inline in the header, then (a) the compiler won't complain about unused functions and (b) you get the maximum available benefit of inlining.

I'm assuming your compiler supports at least the old (C99) standard if not the new (C11) standard. If your compiler only supports the archaic (C89/C90) standard (which is, let's face it, a quarter century old), then you don't have such an easy option — unless there's a non-standard compiler extension that will work roughly the same magic.

See also, amongst others:

Community
  • 1
  • 1
Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • What will C89/C90 complain about or dislike? (I try to write source code that works on variety of compilers including Visual Studio (C89) (I'm sure an #ifdef will solve). Are you saying that by using the inline keyword I get to avoid the warning because inline functions are allowed to have multiple instances (this only applies to a debug build where the symbols wouldn't be stripped)? – B. Nadolson Sep 04 '15 at 03:25
  • Strict C89/C90 didn't support `inline` at all; it will be rejected as a syntax error. And I'm reporting empirical observations on the behaviour of compilers w.r.t `static inline` functions. You can also write them in a regular source file and not use them and the compiler won't care about it not being used — nominally, it can't distinguish that from the header file case. – Jonathan Leffler Sep 04 '15 at 03:27
  • Ah, I see. Well, Visual Studio has __inline and gcc/clang cover about anything else. Thanks for the information on this! It's been a great help. – B. Nadolson Sep 04 '15 at 03:28
  • I'm not surprised to find that MSVC has `__inline`. You can detect that you're working with it and use `#define inline __inline` if you are and I think you're good to go — but I've not verified the MSVC behaviour. – Jonathan Leffler Sep 04 '15 at 03:31
  • VS2015 has `inline` but neither it nor `__inline` have C99 semantics. – cremno Sep 04 '15 at 03:51
  • @cremno: I wish I could say I was surprised. That's why I commented that I've not verified the MSVC behaviour. I wonder if there's a question on SO yet that asks about the differences (between C99 standard behaviour, MSVC behaviour, and maybe the old pre-C99 GNU behaviour, though that is of limited interest now)? – Jonathan Leffler Sep 04 '15 at 03:53
  • I was searching for one and failed to find one. I think it has C++ semantics except for `extern inline` functions which get always emitted. It usually doesn't matter though If only `static inline` is used. – cremno Sep 04 '15 at 04:54
-3

Use inline if you can. I have a feeling this is what it is for.

Samuel Edwin Ward
  • 6,526
  • 3
  • 34
  • 62