5

I recently wrote a piece of C code like that:

static void func1()
{

}

static void func2()
{

}


typedef void (*func_t)(void);

const func_t lookUpTable[FUNC_COUNT] =
{
    [FUNC1] = &func1,
    [FUNC2] = &func2
}

An other programmer worked on the same file and changed it to:

static void func1();
static void func2();

typedef void (*func_t)(void);

const func_t lookUpTable[FUNC_COUNT] =
{
    [FUNC1] = &func1,
    [FUNC2] = &func2
}

static void func1()
{

}

static void func2()
{

}

Since the funcN functions are only called thru the lookup table, I don't actually need the declarations of those functions.

Is it a matter of taste, or is there a coding style that is considered as a good/bad practice?

Cœur
  • 37,241
  • 25
  • 195
  • 267
Plouff
  • 3,290
  • 2
  • 27
  • 45
  • "I don't actually need the declarations" - You still do! Without you cannot use tem in your table. Omitting `static` OTOH does not make the _declaration_ extern, only the name/symbol. – too honest for this site Mar 04 '16 at 13:51
  • There is maybe a problem of vocabulary here. Is it better if I say "I don't need the prototypes"? I mean when I *define* the functions they are *declared* at the same time. Is it part of your point? Regarding the last part of your comment: does it mean that without the `static`, the name/symbol would be public. And so, if this name is used in another translation unit then that the compilation would break because the body/implementation (?) couldn't be found? – Plouff Mar 04 '16 at 14:10
  • 1) use `@name` to addess a comment reliably. Your last comment does not make it more clear to me. Maybe my original comment becomes clearer keeping in mid that I tend to use the standard C vocabulary. Just have a look into it. And you **do** need the prototypes (which **are** _declarations_). And without `static`, a name declared at file-scope has _external linkage_. The term "public" is not used by the standard (and has a different meaning e.g. in C++). – too honest for this site Mar 04 '16 at 14:19
  • @Olaf: Unfortunately I learned programming by myself. So I still have gaps to fill. I'll have a look a the C standard when possible. Thanks! – Plouff Mar 07 '16 at 07:46

1 Answers1

3

It is indeed a matter of taste mostly (and coding style is always somehow a matter of opinion; the style of your partner is consistent with the habit of putting all the code after every other definitions).

In practice, you'll better ensure that your function names are unique (it makes grep-ing for them easier, and gdb will find them more easily) in the entire program, even if they are visible or used only inside one translation unit.

BTW, having your functions being non-static has also some advantages. For example, on Linux, the backtrace(3) & dladdr(3) functions are happier with globally named functions.

Also, sometimes computed gotos and threaded code (or even a plain large switch....) are faster than a table dispatch calling short functions indirectly thru a pointer. (The small overhead of calling functions, e.g. running their prologue and epilogue, might sometimes matter for tiny and quickly running code). See references here & there.

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547
  • Making them `static still is good practice, as it avoids polluting the global namespace. – too honest for this site Mar 04 '16 at 13:48
  • Not always. Some programs are using `backtrace` (e.g. for error report in an interpreter), and then having all the functions being public is wise (in that case, you'll only have `static inline` functions, and the rest being global functions) – Basile Starynkevitch Mar 04 '16 at 13:50
  • 1
    `static inline` is a different matter (note this is C). If you're up to debugging, you should not use certain optimisations anyway (for gcc use `-Og`). – too honest for this site Mar 04 '16 at 13:53
  • Thanks for this amazing answer! You understood that I used the lookup table regarding runtime efficiency improvements. It is used in the FSM of an embedded software. So far we reached the efficiency that we need. The references that you gave may not be needed today but are very interesting! Thanks for the fishing lesson :). – Plouff Mar 04 '16 at 13:59
  • Regarding the static or not static part of your answer, I will need to keep the static attribute. Indeed, this is mandatory in our coding guidelines. And this is not a matter of taste, these are rules! But it is very interesting to know that it can break a backtrace. I some day I develop linux software I'll try to remember that. Thanks again – Plouff Mar 04 '16 at 14:02
  • `backtrace` is *not* for kernel code. It is provided by the GNU libc, and useful in user-land applications – Basile Starynkevitch Mar 04 '16 at 14:03
  • Just changed my comment while you were commenting! – Plouff Mar 04 '16 at 14:04
  • 1
    " It is used in the FSM of an embedded software" - It might be better (more compact, faster) to use a `switch` implementation. Note that on faster MCUs (typically 32bitters like ARM Cortex-M), Flash accesses have waitstates and data-accesses are badly cached (e.g. STM32). – too honest for this site Mar 04 '16 at 14:22
  • @Olaf: Your last comment is a surprise to me. So I created a new question: http://stackoverflow.com/q/35838849/882697 . Could tell what you think? Thanks again! – Plouff Mar 07 '16 at 08:04