1

I want to create a Commons.h file where I can put some shared info, constants, macros and helper functions.

This file has to be included in many part of my application.

If I create function with this syntax I get a Duplicate Symbol error:

int myFunction(int a){ 
   //do something..
}

While if I add the static keyword I get no errors.

static int myFunction(int a){ 
   //do something..
}

1) Is this a valid/right way to add helper functions to a project? 2) What happen exactly adding the static keyword at that definition?

JeremyP
  • 84,577
  • 15
  • 123
  • 161
MatterGoal
  • 16,038
  • 19
  • 109
  • 186
  • 1
    [There can be only one!](http://24.media.tumblr.com/tumblr_m1511oIe4O1rrs79co1_400.jpg) Definition of a function throughout the program, that is. Without the `static` keyword, you get a definition `MyFunction` in every place you include the header, and that's a violation of [One Definition Rule](http://stackoverflow.com/questions/4192170/what-exactly-is-one-definition-rule-in-c). – jrok Sep 10 '13 at 10:00
  • 1
    @jrok Of course, there's also the option of using `inline`... – Angew is no longer proud of SO Sep 10 '13 at 10:02
  • @Angew But that's not really a good idea unless you have performance problems otherwise. The definition of a function does _not_ belong in a header. – James Kanze Sep 10 '13 at 10:27
  • you would be better off putting it all in a e.g. static library and have a header for the library, that way you do not duplicate code all over the place. – AndersK Sep 10 '13 at 10:35
  • One of either the C++ or Objective-C tags is wrong. – JeremyP Sep 10 '13 at 10:40
  • @JeremyP this problem is valid for both Objective-C and C++. – MatterGoal Sep 10 '13 at 11:01
  • @MatterGoal It's also valid for C and that's not there. – JeremyP Sep 10 '13 at 11:02
  • @JeremyP In that case I forgot one tag :P What do you suggest to do? I found this problem working with an Objective-C project but I suppose that is related with C++/C. – MatterGoal Sep 10 '13 at 11:58
  • @MatterGoal If you edit your post, you can add tags. However, now you've confirmed that it's OK to put the C tag in, I've already done it for you. – JeremyP Sep 10 '13 at 12:51
  • @MatterGoal, The semantic of those two example will be very different if there is static variable in the function scope. There will multiple instance of the static variable. – ZijingWu Sep 10 '13 at 13:02

2 Answers2

4

Not really. You're creating a separate instance of the function in every translation unit. What you should do is only declare the function in the header:

extern int myFunction( int a );

and define it in a source file somewhere. (Note that the extern above is optional, since it is implicit for all function declarations, and it is usual to omit it. I add it here only to stress the fact that you are declaring, and not defining.)

James Kanze
  • 150,581
  • 18
  • 184
  • 329
  • So if I want to create a set of helper functions, is a good practice to create the header with prototypes and just move the implementation in the source file. I saw that Apple in its implementation of CoreGraphics use the inline keyword for the most of its "helper" functions. So I just try to figured out which is the better way to do it. – MatterGoal Sep 10 '13 at 10:49
  • 1
    @MatterGoal Putting the implementation in a separate source file is the usual solution. Generally, `inline` should be avoided, as it increases coupling. (The implementation of the function is visible in the header, which you want to avoid.) It's more of an optimization technique, to be used when the profiler says you have to. – James Kanze Sep 10 '13 at 11:18
1

If you use the keyword static before a function declaration, then you only can use this function inside the actual translation unit (.cpp, .c or .m), where it was defined.

So it is the opposite of the keyword extern, extern is the default storage class specifier for functions.

The use for a helper function is then wrong, because it doesn't even compile.

Instead you should declare the function in the helper file as extern. And use it without implementing it again. You can implement it once in the .c/.cpp/.m of the helper .h.

If you use a function as a helper function for other files, then it is good practice to use the extern keyword, even though it is not needed. It is a hint for programmers, this function is used somewhere else.

Binarian
  • 12,296
  • 8
  • 53
  • 84
  • ??? His static wasn't on a class member (or at least he didn't say so if it was). `static` is the opposite of `extern`, but only on free functions, not on members; `extern` isn't legal on class members. – James Kanze Sep 10 '13 at 10:26
  • He doesn't say it is a member of anything. What class? – Binarian Sep 10 '13 at 10:26
  • I know. But you talk about using the function "inside the actual class". Anything inside a class is a member. – James Kanze Sep 10 '13 at 10:28
  • The first sentence is incorrect. static functions are accessible anywhere within the compilation unit (i.e. the `.c` or `.m` file being compiled) – JeremyP Sep 10 '13 at 10:38
  • Oh yes, I mean translation unit, thanks for correcting. Now I understand. Sorry @JamesKanze , my fault. – Binarian Sep 10 '13 at 10:45
  • My function is not member of a class. Is just a generic helper function. – MatterGoal Sep 10 '13 at 10:50
  • I know. But it is part of a translation unit, there declare it as extern or nothing (defaults to extern) – Binarian Sep 10 '13 at 10:52