3

is it possible to have 2 (or more) different implementations for the same function declared in a header file? I'll give an example - let's say we have a header file called common.h and 2 source files called src1.c and src2.c.

common.h

//lots of common function declarations implemented in some file common.c 
int func(int a, int b);

src1.c

#include "common.h"

int func(int a, int b)
{
    return a+b;
}

src2.c

#include "common.h"

int func(int a, int b)
{
    return a*b;
}

let's say that I want each of the source file to use its local version of func(). is it possible to do so?

noamgot
  • 3,962
  • 4
  • 24
  • 44
  • 2
    Those are two different **functions** with the same name. – Pete Becker Jan 19 '17 at 16:46
  • If you want to have different implementations in different files, why do you want to share the function in a header in the first place? – DeiDei Jan 19 '17 at 16:46
  • 4
    Make the functions `static`; they're then local to their source file (translation unit) and each file can use its own. There'd be no declaration in the common header, though. – Jonathan Leffler Jan 19 '17 at 16:46
  • @EugeneSh. The question is about the common subset of C and C++, and valid in both languages, so I think it is appropriate to tag as both. – Erik Alapää Jan 19 '17 at 16:49
  • @DeiDei - I was thinking about it pretty much like interfaces in java, where 2 java files can implement the same interface in 2 different face. – noamgot Jan 19 '17 at 16:50
  • When you call func(), under what conditions do you want it to call src1 or src2. Something has to decide which, and knowing what this is would help us to answer the question. – James Jan 19 '17 at 16:58

5 Answers5

6

Yes, but if you attempted to link your main program against both src1 and src2 you would encounter an error because it wouldn't know which definition to use.
Headers are just ways for other code objects to be aware of what's available in other objects. Think of headers as a contract. Contracts are expected to be filled exactly one time, not zero or multiple times. If you link against both src1 and src2, you've essentially filled the int func(int a, int b); contract twice.

If you need to alternate between two functions with the same signature, you can use function pointers.

Community
  • 1
  • 1
Mr. Llama
  • 20,202
  • 2
  • 62
  • 115
1

If you want each source file to only use its local implementation of func, and no other module uses those functions, you can remove the declaration from the header and declare them as static.

src1.c

static int func(int a, int b)
{
    return a+b;
}

src2.c

static int func(int a, int b)
{
    return a*b;
}

By doing this, each of these functions is only visible in the module it is defined in.

EDIT:

If you want two or more functions to implement an interface, you need to give them different names but you can use a function pointer to choose the one you want.

common.h

typedef int (*ftype)(int, int);
int func_add(int a, int b);
int func_mult(int a, int b);

src1.c

#include "common.h"

int func_add(int a, int b)
{
    return a+b;
}

src2.c

#include "common.h"

int func_mult(int a, int b)
{
    return a*b;
}

Then you can chose one or the other:

ftype func;
if (op=='+') {
    func = func_add;
} else if (op=='*') {
    func = func_mult;
...
}

int result = func(value1,value2);
dbush
  • 205,898
  • 23
  • 218
  • 273
  • if I take them out of the header - what advantage does the static declaration gives me? – noamgot Jan 19 '17 at 16:52
  • @noamgot A function declared as `static` is only visible to the containing source file. It allows other static functions with the same name to be declared in other modules. – dbush Jan 19 '17 at 16:55
  • but if the functions are not declared anywhere, why does it matter? aren't they unreachable outside their source file anyway? – noamgot Jan 19 '17 at 17:04
  • 1
    @noamgot Even without a declaration, you can't have more than one non-static function with a given name. – dbush Jan 19 '17 at 17:06
  • @noamgot I made updates related to your comment about interfaces. – dbush Jan 19 '17 at 17:06
  • The header file does not strictly 'declare' a function, it just tells the compiler how to call it. So you can call a non static func from another C file by declaring it in the C file `int func(int a, int b);` first. Of course this is a terrible think to do because you can declare different arguments and at run-time it will go horribly wrong. So .h files are strongly advised to share public functions - and if you don't want it called from another module always make it static. – James Jan 19 '17 at 17:12
  • @James, the OP's and this answer's example header files exactly *do* "declare" functions `func()`, `func_add()`, and `func_mult()`. Informing the compiler how to call them is one of the results of declaring them. – John Bollinger Jan 19 '17 at 17:19
  • @dbush, don't forget inline functions. You can have as many non-static functions with a given name as you have translations units, provided that no more than one of them is non-inline. Inline functions can (technically) have external linkage, even though they are not accessible from foreign TUs. This is approximately true even in C++, though C++ has some additional rules in this area relative to C. – John Bollinger Jan 19 '17 at 17:22
0

If you compile it with each src[x].c, you'll be able to use it in any function of your .c

FireWing
  • 21
  • 5
0

You can decide to not expose the function implementation to other translation units. In c, use keyword static before the function signature right where you implement the function (see code below); In C++, you can also use unnamed namespaces. By doing so, the linker will not give you an error, and each translation unit will use it's own implementation:

Suppose the following two translation units main.c and another.c. Both have their (private) implementation of int function(a,b), such that they yield different results when calling it:

extern void someOtherFeature();

static int function (a,b) {
    return a+b;
}

int main(){

    int x = function(1,2);
    printf("main: function(1,2)=%d\n", x);
    someOtherFeature();
}

// another.c:
#include <stdio.h>

static int function (a,b) {
    return a*b;
}

void someOtherFeature() {
    int x = function(1,2);
    printf("someOtherFeature: function(1,2)=%d\n", x);
}

Output:

main: function(1,2)=3
someOtherFeature: function(1,2)=2

However, if both translation units exposed their implementations (i.e. both omitted keyword static, then the linker would report an error like duplicate symbol _function in:....

Stephan Lechner
  • 34,891
  • 4
  • 35
  • 58
0

If you want each source file to use a local version of func, just put it in an unnamed namespace:

For example src1.C:

namespace
{
    int func(int a, int b)
    {
        return a+b;
    }
}

Then each source file will use its own version. You don't need to declare it in the header.

Note that your original code with the definitions at global namespace and declared in the header violates the one definition rule (two function definitions for the same name must always have the same definition), invoking undefined behavior, no diagnostic required.

Mark B
  • 95,107
  • 10
  • 109
  • 188