Errors when using pointers to static functions in C / C ++ - c++

I am compiling with g ++ an application that calls some functions defined in a "C" library.
Some of the functions that I need to call are defined as static in the original ".c" file (I know that when a function is defined static it is so that it is not called from outside of that file, but despite that, I need to call them from outside of the same).
I am going to execute them from outside that file using pointers to functions and to see how they work, I have prepared this example, where I want to execute in file_2.c the static functions fun5 and fun6 defined in file_1.c
file_1.h
--------
#ifndef FILE_1_H
#define FILE_1_H
int (*getPtrFun6(void*))(int,char,char*);
#endif
file_1.c
--------
#include <stdio.h>
int(*ptr_fun5)(int,int);
static int fun5(int p1, int p2)
{
printf("fun5 called.\n");
ptr_fun5 = &fun5;
return p1 + p2;
}
static int fun6(int p1, char p2, char* p3)
{
printf("fun6 called with p1 = %d, p2 = %c, p3 = %s.\n", p1, p2, p3);
return p1;
}
int (*getPtrFun6(void*))(int,char,char*)
{
return fun6;
}
file_2.c
--------
#include <stdio.h>
#include <cstring>
#include "file_1.h"
extern int(*ptr_fun5)(int,int);
extern int(*ptr_fun6)(int,char,char*);
int main(void)
{
int returnValue = 0;
// To run fun5
returnValue = (ptr_fun5)(15, 32);
printf ("Returns %d\n", returnValue);
// To run fun6
char myString[50];
memset(myString,0,50);
strncpy(myString,"THIS IS OK",10);
ptr_fun6 = getPtrFun6();
returnValue = (ptr_fun6)(32, 'v', myString);
printf ("Returns %d\n", returnValue);
return 0;
}
I compile the program with the command:
g++ file_2.c file_1.c -o static_example
As you can see from the source code, I have tried two different ways to use a pointer to a static function.
If I comment on everything about fun6 in the source code, compile it and run it (just call fun5) I get the error "Segmentation fault".
On the other hand, if I comment on everything related to fun5 in the source code and leave only fun6, when compiling the program, I get these errors:
file_2.c: In function ‘int main()’:
file_2.c:20:25: error: too few arguments to function ‘int (* getPtrFun6(void*))(int, char, char*)’
ptr_fun6 = getPtrFun6();
^
In file included from file_2.c:4:
file_1.h:4:7: note: declared here
int (*getPtrFun6(void*))(int,char,char*);
^~~~~~~~~~
I have looked at various forums and tutorials on the web and I don't see what the error is, so I would need some help on the correct way to use the pointers to fun5 and fun6.

(just call fun5) I get the error "Segmentation fault".
Because fun5 is uninitialized, it doesn't point anywhere.
when compiling the program, I get these errors: ... error: too few arguments to function
So why did you declare it to take a void* as parameter? If you don't want that, then it should be void.
General advise:
Get rid of global variables with extern.
Use typedef whenever dealing with function pointers, so that the code can be read by humans. Evidentally, int (*getPtrFun6(void*))(int,char,char*) isn't readable even by yourself.

int (*getPtrFun6(void*))(int,char,char*);
Confusing syntax is leading to wrong prototype and declaration.
The easy to read way (function pointers are same as "normal" pointers):
typedef int fun6type(int, char, char *);
fun6type *getPtrFun6(void);
fun6type *getPtrFun6(void)
{
return fun6;
}
Hard to read way:
int (*getPtrFun6_1(void))(int, char, char *);
int (*getPtrFun6_1(void))(int, char, char *)
{
return fun6;
}
int foo(void)
{
int (*f)(int, char, char *) = getPtrFun6_1();
return f(1, 'a', "Test");
}
Test it yourself
https://godbolt.org/z/erh63jTc8
If I comment on everything about fun6 in the source code, compile it
and run it (just call fun5) I get the error "Segmentation fault".
Function pointer has to reference a valid function before it is dereferenced (called) as any other pointer. Your one is not initialized and it is not referencing a valid function.
BTW It is rather C code (not C++). In C++ use of function pointers (and generally pointers) should be avoided.

returnValue = (ptr_fun5)(15, 32); does not work because ptr_fun5 is initialized to a null pointer and is not given any other value until the statement ptr_fun5 = &fun5; inside fun5 is executed, which does not happen until fun5 is called.
One way to fix that is to delete int(*ptr_fun5)(int,int); and put int (*ptr_fun5)(int, int) = fun5; after the declaration of fun5. Then it will be initialized to the address of fun5.

Related

Why can't I use my function in the header file?

main.h: header
#ifndef _MAIN_H
#define _MAIN_H
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct ComplexNum
{
double real;
double img;
}mc;
char *JustShow(mc );
#endif // _MAIN_H
cal.cpp : function defined in another file called
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include "main.h"
char *JustShow(mc a)
{
char str1[100];
char str2[100];
char str3 [100];
sprintf(str1,"%f",a.real);
sprintf(str2,"%f",a.img);
strcat(str1," + ");
strcat(str1,str2);
strcat(str1,"i");
return(str1);
}
I tried to use the JustShow function in another file, but the compiler said undefined reference to 'JustShow'
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include "main.h"
int main()
{
mc y;
y.img = 4;
y.real = 3;
printf("%s",JustShow(y));
}
I am so confused why can't I use the function JustShow when I had already added "main.h". I am also confused why should we define the functions in the source file instead of the header.
I'm sorry if this is the basic knowledge I should learn about and not ask others.
I'm going to call the third piece of code "main.cpp".
why can't I use the function JustShow when I had already added "main.h".
Header files only inform a compiler that a function, variable or constant exist. You need to compile cal.cpp with main.cpp: g++ main.cpp cal.cpp -o main
I am also confused why should we define the functions in the source file instead of the header.
It makes code more organised.
It speeds up compile time.
You can read more about header files here
Some advice for your code:
Function JustShow is incorrect. Arrays are just pointers and you are returning a pointer to a local variable that are deleted after function returns. It means that it will be overwritten and you will lose data there (and trying to write there may crash your program). In order to make it work you can:
Give an array as an argument to the function. Then we would have void JustShow(mc a, char* str1);
create new array with new (or malloc if you wirte in C, not C++).
You don't need to concat so much. sprintf can do all of that:
void JustShow(mc a, char* str1) {
sprintf(str1,"%f + %fi", a.real, a.img);
}

Exception in C++ with function pointers: Access violation executing location 0x00000000

I'm having some trouble with function pointers and passing them as inputs to other functions in C++. I've written some simplified code that sums up the trouble that I'm having. I have two .cpp files as below
functions.cpp
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#define _CRT_SECURE_NO_WARNINGS
typedef double(*real_function)(double);
double one(double x) {
return double(1);
}
void applyfunction(int length, real_function f, double* result) {
int j;
result[0] = 0;
for (j = 1; j < length; j++) {
result[j] = f(result[j - 1]);
}
}
Source.cpp
#include <iostream>
#include <stdio.h>
#include <stdlib.h>
#define _CRT_SECURE_NO_WARNINGS
typedef double(*real_function)(double);
real_function one;
void applyfunction(int, real_function, double*);
int main(void) {
double* result;
result = (double*)calloc(10, sizeof(double));
applyfunction(10, one, result);
return(0);
}
When I compile this, I get the following error in Visual Studio 2015
Exception thrown at 0x00000000 in Project3.exe: 0xC0000005: Access violation executing location 0x00000000.
If there is a handler for this exception, the program may be safely continued.
What is going wrong? The funny thing is that if we define those functions one and applyfunction in the source.cpp file (i.e. put all code in a single file), things seem to work. So, I think that it must be something very simple that I am getting wrong. Thank you for any help.
real_function one;
This creates a global variable one which is initialized to a null pointer.
applyfunction(10, one, result);
You then pass that null pointer to applyfunction...
result[j] = f(result[j - 1]);
...wherein you try to call it, generating the null pointer exception.
To fix this, don't create a variable one in Source.cpp. Instead, add a prototype that matches the definition in functions.cpp. In other words, replace real_function one; with
double one(double x);
real_function one;
doesn't declare the function one in the other file; it defines a function pointer called one. Because it's global (and thus has static storage), it's initialized to null. Your program crashes because it's trying to call a null pointer.
One way to fix this is to change
typedef double(*real_function)(double);
to
typedef double real_function(double);
This way real_function actually names a function type (not a pointer).

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.

global const variable definition - access through extern in c++

I read some answers about this topic, but I am still not sure:
In C++ a global const variable definition is automatically static. However I can access it from another cpp-file through extern:
// module.cpp
const int i = 0;
and
// main.cpp
extern const int i;
int main ()
{
if (i > 10)
return 0;
else
return 1;
}
Why is this possible (accessing an object with internal linkage from another module)? Normally I should be forced to define i as extern const int i = 0 in module.cpp, to have an explicitely global but non-static const, or?
In comparison, this is not possible:
// module.cpp
static int i = 0;
and
// main.cpp
extern int i;
int main ()
{
i = 10; // but read-only access like (i > 10) would be possible!
return 0;
}
So is the answer that: yes, you can access internal linked objects from other modules, but only for read (so always with const)?
Edit:
Sorry, but I made a mistake: in my original code I just tried an expression without effect (in both examples):
extern const int i; // or extern int i for second example
int main ()
{
i>10;
return 0;
}
I thought, that it behaves the same, as if program flow or data was dependent of this expression, but in fact it does not! The compiler seems to just cut out this effectless expression, so that the linker does not see it! So all is alright: in the first example i must be indeed defined extern const int i = 0 in module.cpp, and in the second example i cannot be accessed at all (unless in effectless expression). Compiler is VC++2010.
Edit2:
However, now I don't understand why this is possible:
// module.cpp
extern const int i = 0;
and
// main.cpp
int i = 99;
int main ()
{
bool b = i>10;
return 0;
}
i have both external linkage. But no error. When in module.cpp I define int i = 0, then error (multiple symbols). Why?
As for me it looks like a compiler bug. Constant variable i is not defined It is only declared in main.cpp. As for variable i in module.cpp then it has internal linkage and shall not be accessible outside the module.
Relative to your addition to the original post then the compiler has nothing common with this situation. It is linker that checks whether there are duplicate external symbols. I think it decided that if one variable has qualifier const and other has no it then there are two different variables. I think that it is implementation defined whether the linker will issue an error or not. Moreover it can have some options that could control the behaviour of the linker in such situations.

declaration syntax error

What's wrong with this one? The compiler says: Declaration syntax error.
Source File:
#include<iostream>
using namespace std;
int main(int argc, char **argv) {
void printBinary(const unsigned char val) {
//printBinary() func. outputs byte in binary
for(int i=7;i>=0;i--)
if(val & (1<<i)) //generates a single bit with offset position
std::cout<<"1";
else
std::cout<<"0"
}
return 0;
}///:~
Header file:
void printBinary(const unsigned char val);
///:~
You are trying to define one function inside another function. This is illegal. Why did you place the definition of printBinary into the body of main?
Aside from the lambda functions in C++11, C++ has no such feature as local functions. All functions "live" in namespace scope.
The only workaround for this rule is inline member function definitions for local classes, although it does not produce a local function either.
You can't define a function in another function's (in this case, main) body.
//EDIT: Unless, of course, it's lambda.