different implementations for the same function (c/c++) - c++

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?

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.

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);

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

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:....

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.

Related

Make a object accessible by only its library, and not by any other routine in the program

Lets say I have two (or more) c functions func1() and func2() both requiring a buffer variable int buff. If both functions are kept in separate files, func1.c and func2.c, How do I make it so that buff is accessible to only func1() and func2() and not to the calling routine(or any other routine).
Here is an example setup:
file func1.c:
/*func1.c*/
static int buff;
int *func1(int x)
{
buff = x;
return &buff;
}
file func2.c:
/*func2.c*/
static int buff;
int *func2(int x)
{
buff = x;
return &buff;
}
header header.h:
/*header for func1.c and func2.c*/
//multiple inclusion guard not present.
int *func1(int);
int *func2(int);
file main.c:
#include<stdio.h>
#include"header.h"
int main()
{
int *ptr;
ptr = func1(1);
printf("&buff = %p , buff = %d\n", ptr, *ptr);
ptr = func2(2);
printf("&buff = %p , buff = %d\n", ptr, *ptr);
return 0;
}
As expected, the output shows different memory locations for buff.
&buff = 0x55b8fd3f0034 , buff = 1
&buff = 0x55b8fd3f0038 , buff = 2
But I need only one copy buff, not more.
I could of course, put both functions in the same file, and define buff as static int but then I would lose the ability to compile the functions separately.
If I put int buff in a separate buff.c and declare it extern in func1.c and func2.c, but then it would be easily accessible by the calling routine(main in this case).
Basically, I need to create a library of functions that work on the same external object, that is accessible only to them. The calling routine may not need all the functions, so I do not want to put them in a single file and create unused code. But there must be only one copy of the object.
Please help on how I could do the same, if it is achievable.
The C standard does not provide a way to do this. It is usually done using features of compilers and linkers beyond the C standard. Here is an example using Apple’s developer tools on macOS. For options suitable to your environment, you should specify the build tools and versions you are using, such as whether you are using Apple tools, GNU tools, Microsoft tools, or something else.
With this in a.c:
#include <stdio.h>
int x = 123;
void a(void)
{
printf("In a.c, x is %d.\n", x);
}
and this in b.c:
#include <stdio.h>
extern int x;
void b(void)
{
printf("In b.c, x is %d.\n", x);
}
we compile the source files to object modules:
clang -c a.c b.c
and then link them to a new object module r.o while requesting that the symbol x (_x in the linker view) not be exported:
ld -r -o r.o -unexported_symbol _x a.o b.o
Then, if we have another source file c.c that attempts to use x:
#include <stdio.h>
extern int x;
extern void a(void);
extern void b(void);
int main(void)
{
a();
b();
printf("In c.c, x is %d.\n", x);
}
attempting to build an executable with it using clang -o c c.c r.o yields:
Undefined symbols for architecture x86_64:
"_x", referenced from:
_main in c-139a35.o
ld: symbol(s) not found for architecture x86_64
However, if we remove the two lines in c.c that refer to x, the build succeeds, and the program prints:
In a.c, x is 123.
In b.c, x is 123.
One typical approach to this problem is to give the global variable a name that begins with _.
That is, in func1.c you might write
int _mylib_buff;
And then in func2.c, of course, you'd have
extern int _mylib_buff;
Now, of course, in this case, _mylib_buff is technically an ordinary global variable. It's not truly "private" at all. But global variables beginning with _ are private "by convention", and I'd say this works okay in practice. But, obviously, there's nothing preventing some other source file from cheating and peeking at the nominally-private variable, and there's no way in Standard C to prevent one from doing so.
The other complication is that some identifiers beginning with _ are reserved to the implementation, and you're not supposed to use them in your own code. (That is, components of the implementation -- like your C compiler and C library -- have semi-global variables they're trying to hide from you, and they're typically using a leading _ to achieve this, also.) I'm pretty sure the rules say it's okay for you to define a global variable beginning with a leading underscore followed by a lower-case letter, but the rules are somewhat complicated, and I can never remember all the nuances. See questions 1.9 and 1.29 in the C FAQ list.
The answer is: It's not possible.
C has no way of saying "this variable may be used by source file x, y, z and not by any other sources files".
So if you want buff to be "private" to a number of functions, you'll have to put those functions in the same source file.
You need to define the non-static variable in one of the files for example:
int buff;
int *func1(int x)
{
buff = x;
return &buff;
}
in the header file declare it as extern:
/*header for func1.c and func2.c*/
//multiple inclusion guard not present.
extern int buff;
int *func1(int);
int *func2(int);
Include it in all other files:
/*func2.c*/
#include "header.h"
int *func1(int x)
{
buff = x;
return &buff;
}
If you do not want variable to be visible you need to create function which will get and set the "hidden" variable.
typedef enum
{
GET,
SET,
REF,
}OP_t;
#define CREATE(type, name) type getset##name(OP_t oper, type val, type **ref) \
{\
static type buff;\
switch(oper)\
{\
case GET:\
return buff;\
case SET:\
buff = val;\
break;\
case REF:\
if(ref) *ref = &buff;\
break;\
}\
return 0;\
}\
#define HEAD(type, name) type getset##name(OP_t oper, type val, type **ref)
#define GETVAL(name) getset##name(GET, 0, NULL)
#define SETVAL(name,val) getset##name(SET, val, NULL)
#define GETREF(name,ref) getset##name(REF, 0, ref)

How to make a variable available to multiple .cpp files using a class?

This question has derived from this one.
I have a working program which must be split into multiple parts. In this program is needed to use a variable (now it's a GTK+ one :P) many times in parts of the program that will end up in separated .cpp files.
So, I made a simple example to understand how to make variables available to the program parts. A modified version of the previous code would be:
#include <iostream>
using namespace std;
int entero = 10;
void function()
{
cout<<entero<<endl;
//action1...;
}
void separated_function()
{
cout<<entero<<endl;
//action2...;
}
int main( int argc, char *argv[] )
{
function();
separated_function();
cout<<entero<<endl;
//something else with the mentioned variables...;
return 0;
}
It is needed to split the code correctly, to have function(), another_function() and main() in separated .cpp files,and make entero avaliable to all of them... BUT:
In the previous question #NeilKirk commented:Do not use global variables. Put the required state into a struct or class, and pass it to functions as necessary as a parameter (And I also have found many web pages pointing that is not recommended to use global variables).
And, as far I can understand, in the answer provided by #PaulH., he is describing how to make variables avaliable by making them global.
This answer was very useful, it worked fine not only with char arrays, but also with ints, strings and GTK+ variables (or pointers to variables :P).
But since this method is not recommended, I would thank anyone who could show what would be the correct way to split the code passing the variables as a function parameter or some other method more recommended than the - working - global variables one.
I researched about parameters and classes, but I'm a newbie, and I messed the code up with no good result.
You need to give the parameter as a reference if you want the same comportement as a global variable
#include <iostream>
using namespace std;
// renamed the parameter to avoid confusion ('entero' is valid though)
void function(int &ent)
{
cout<<ent<<endl;
++ent; // modify its value
//action1...;
}
void separated_function(int &ent)
{
cout<<ent<<endl;
++ent; // modify its value again
//action2...;
}
int main( int argc, char *argv[] )
{
int entero = 10; // initializing the variable
// give the parameter by reference => the functions will be able to modify its value
function(entero);
separated_function(entero);
cout<<entero<<endl;
//something else with the mentioned variables...;
return 0;
}
output:
10
11
12
Defining a class or struct in a header file is the way to go, then include the header file in all source files that needs the classes or structures. You can also place function prototypes or preprocessor macros in header files if they are needed by multiple source files, as well as variable declarations (e.g. extern int some_int_var;) and namespace declarations.
You will not get multiple definition errors from defining the classes, because classes is a concept for the compiler to handle, classes themselves are never passed on for the linker where multiple definition errors occurs.
Lets take a simple example, with one header file and two source files.
First the header file, e.g. myheader.h:
#ifndef MYHEADER_H
#define MYHEADER_H
// The above is called include guards (https://en.wikipedia.org/wiki/Include_guard)
// and are used to protect the header file from being included
// by the same source file twice
// Define a namespace
namespace foo
{
// Define a class
class my_class
{
public:
my_class(int val)
: value_(val)
{}
int get_value() const
{
return value_;
}
void set_value(const int val)
{
value_ = val;
}
private:
int value_;
};
// Declare a function prototype
void bar(my_class& v);
}
#endif // MYHEADER_H
The above header file defines a namespace foo and in the namespace a class my_class and a function bar.
(The namespace is strictly not necessary for a simple program like this, but for larger projects it becomes more needed.)
Then the first source file, e.g. main.cpp:
#include <iostream>
#include "myheader.h" // Include our own header file
int main()
{
using namespace foo;
my_class my_object(123); // Create an instance of the class
bar(my_object); // Call the function
std::cout << "In main(), value is " << my_object.get_value() << '\n';
// All done
}
And finally the second source file, e.g. bar.cpp:
#include <iostream>
#include "myheader.h"
void foo::bar(foo::my_class& val)
{
std::cout << "In foo::bar(), value is " << val.get_value() << '\n';
val.set_value(456);
}
Put all three files in the same project, and build. You should now get an executable program that outputs
In foo::bar(), value is 123
In main(), value is 456
I prefer to provide a functional interface to global data.
.h file:
extern int get_entero();
extern void set_entero(int v);
.cpp file:
static int entero = 10;
int get_entero()
{
return entero;
}
void set_entero(int v)
{
entero = v;
}
Then, everywhere else, use those functions.
#include "the_h_file"
void function()
{
cout << get_entero() << endl;
//action1...;
}
void separated_function()
{
cout << get_entero() << endl;
//action2...;
}
int main( int argc, char *argv[] )
{
function();
separated_function();
cout<< get_entero() <<endl;
//something else with the mentioned variables...;
return 0;
}
If you do not plan to modify the variable, it is generally ok to make it global. However, it is best to declare it with the const keyword to signal the compiler that it should not be modified, like so:
const int ENTERO = 10;
If you are using multiple cpp files, also consider using a header file for your structures and function declarations.
If you are planning on modifying the variable, just pass it around in function parameters.

C++: Defining void* array in header file and declaring it in a cpp file?

I saw this question and I tried to do as the answer to that question said. To use the extern keyword in the header file to define an array and then declare it outside of that namespace or class in a other cpp file.
It didn't work for me really, I'm not sure if it because I'm using a void pointer array (i.e void* array[]) or if it's just my ignorance that prevents me from seeing the problem.
This is the shortest example I can come up with:
[cpp.cpp]
#include "h.h"
void main(){
void* a::b[] = {
a::c = a::d(1)
};
}
[h.h]
namespace a{
struct T* c;
struct T* d(int e);
extern void* b[];
}
So the problem is that I receive the error:
IntelliSense: variable "a::b" cannot be defined in the current scope
And I have no clue why that is.
First, you should declare main() as int ! See here why.
Declaring your array as extern in a namespace means that it belongs to the namespace but is defined somewhere ele, normally in a separate compilation unit.
Unfortunately, in your main(), you try to redefine the element as a local variable. This explains the error message you receive.
You shoud do as follows:
#include "h.h"
void* a::b[] { a::c, a::d(1) }; // global variable belonging to namespace
int main() // int!!!
{
/* your code here */
}
The code will compile. The fact that a::b[] is defined in the same compiling unit is accepted. But the linker will complain because a::d(1) is a call to the function d returning a pointer to a struct, and this function is defined nowhere.
Therfore you should also define this:
namespace a {
struct T* d(int e)
{
return nullptr; // in reality you should return a pointer to struct T
}
}
Interestingly, struct T does not need to work for this code to compile and link.

why free function inside namespace is ambiguous?

--myfunc.hh
#ifndef MY_FUNC_HH
#define MY_FUNC_HH
namespace abc
{
int xyz (int a, int b);
}
#endif
--myfunc.cc
#include "myfunc.hh"
using namespace abc;
int xyz (int a, int b)
{
if (!b)
return 0;
return xyz (b, b/a);
}
$ g++ -c -g myfunc.cc myfunc.hh
myfunc.cc: In function ‘int xyz(int, int)’:
myfunc.cc:9: error: call of overloaded ‘xyz(int&, int)’ is ambiguous
myfunc.cc:5: note: candidates are: int xyz(int, int)
myfunc.hh:6: note: int abc::xyz(int, int)
Why is xyz overloaded when there's only one function named xyz defined here?
isn't the using namespace abc telling the compiler to look for name xyz in namespace abc?
For example, when you use the std::copy function
#include <algorithm>
using namespace std;
void afunction()
{
copy(blah, blah, blah);
}
all works fine, why should abc::xyz be any different here? Or, is it because the recursive call? if so, why?
I think in myfunc.cc you want to write
#include "myfunc.hh"
namespace abc {
int xyz (int a, int b)
{
if (!b)
return 0;
return xyz (b, b/a);
}
}
This way you define the abc::xyz function you declared in the .h file. The way you wrote it you define an xyz function outside the namespace abc while also importing the one which was declared in the namespace. Thus the ambiguity.
Agreeing with #cHao and #JonathanWakely suggestion, I favor this better syntax:
int abc::xyz (int a, int b)
{
if (!b)
return 0;
return xyz (b, b/a);
}
Indeed it ensure that abc::xyz has been correctly declared in the header file.
There is a difference between these two codes:
-- myfunc.cc
#include "myfunc.hh"
using namespace abc;
int xyz (int a, int b)
{
if (!b)
return 0;
return xyz (b, b/a);
}
-- myfunc.cc
#include "myfunc.hh"
namespace abc {
int xyz (int a, int b)
{
if (!b)
return 0;
return xyz (b, b/a);
}
}
The first makes use of abc namespace, but xyz is defined at the "top" namespace; there are 2 functions defined. The second gives the implementation of the abc::xyz function.
In your case you want to do the second.
In your myfunc.cc file you overload the function xyz. That means you are defining a completely new function. There is one that is local in global namespace, there is one in the namespace abc.
The statement using namespace abc; in your example, introduces the ambiguity actually, rather than solving it. Your call is ambiguous in the sense that compiler have no idea which function to call.
Your question seems to be asking why there are two versions of xyz(int, int) visible when you explicitly went and told the compiler to make xyz(int, int) visible and then defined another one?
What, exactly, do you expect the compiler to do here? It isn't going to guess for you so it gives you an error.
If you need to call one or the other, use the scope operator and an explicit namespace. You could call ::xyz(1, 2) or abc::xyz(1, 2) for example.

Linker error-Calling function in C++ file from C file

I am trying to execute basic code in C and C++ in Linux environment.
I am using eclipse to run it. Current project is created as C project.
All I am trying to do is to call a function from different file in same folder.
I have my main in sample.c, In main I would like to call function sum(int a, int b) in A.c. I was able to run it. But when I rewrite same function sum in A.cpp(a C++ template file) it throws linker error.
gcc -o "Test" ./sample.o
./sample.o: In function
main':/home/idtech/workspace/Test/Debug/../sample.c:19: undefined
reference to sum' collect2: ld returned 1 exit status make: * [Test]
Error 1
I need help in calling functions in C++ file from C file in same folder.
Please help me to solve this linker issue.
Thanks
Harsha
The C++ compiler mangles symbol names in order to encode type information. Typically, when writing C++ functions that should be exposed to C code, you'll want to wrap the function in an extern "C" { ... } block, like so (or just prefix it with extern "C" as #DaoWen pointed out):
A.cpp:
extern "C" {
int sum(int a, int b)
{
return a+b;
}
}
caller.c:
extern int sum(int a, int b);
...
int main() { sum(42, 4711); }
By marking a function as extern "C", you're sacrificing the ability to overload it, because different overloads are distinguishable only by their mangled symbol names, and you just requested that mangling be turned off! What it means is that you cannot do this:
extern "C" {
int sum(int a, int b) { return a+b; }
float sum(float a, float b) { return a+b; } // conflict!
}