Calling a uninitialized variable that is a function in C t - c

I have the following situation:
int aFunction() {
int cc;
double *doubleValue;
double atod();
*doubleValue = atod ("12.3", &cc);
}
As far I understand atod is a pointer to a function, which returns a double, and it seems that, when atod is called, it is not initialized.
Am I right? What can happen, as this code is running in production?

Drop that code from production immediately.
You're dereferencing an uninitialized pointer and getting undefined behavior:
double *doubleValue;
*doubleValue = ...
Anyway this:
double atod();
is a prototype of a function which takes an unspecified number of arguments (and might cause a linking error if it's not defined elsewhere) and returns a double. To have a function pointer you should rather write:
double function() {
return 2.0;
}
int main()
{
double (*atod)(); // Pointer to function
atod = &function;
}
Example

A function pointer would look like this:
double (*atod)();
What you have is a prototype. If you put it outside your function, you'd recognise it:
double atod();
int aFunction() {
int cc;
double *doubleValue = malloc(sizeof(double));
*doubleValue = atod ("12.3", &cc);
}
The compiler/linker simply finds the atod function from somewhere else.
I don't why anybody would choose to do this, rather than include the proper header file.
(I'm assuming the error with the uninitialized double * is caused by you reducing the example.)

There are the following problems I can see from the first glance:
doubleValue is a pointer. You have to allocate a memory underneath before you're trying to dereference it and assign atod() result into.
atod() should be implemented in some library (or imported from shared library), otherwise your code will compile and will not link.

What confused me was I didn't know one could put prototypes inside the body of a function, so I, wrongly, assumed it was a pointer for a function that was never initialized. I searched and found the atod function defined in another library. The code is correct.
The doubleValue error was my mistake, in trying to simplify the problem whne presenting it to you. In reality doubleValue is a parameter of the aFunction, and is already initialized.
Thanks everybody again. You have been very quick and helpfull.

Related

Defining A Function Pointer Using Assignment In c

I'm learning C. I know what the first line is doing; it's making a pointer to a function with no arguments and it returns an int. But wtf is the second doing?
My guess is that it is casting an int into a function? But what does it mean to turn an int into a function?
Also, why does it cause an error when I try to call the function: 'function()'?
int (*function) ();
function = (int (*) ()) (1000);
Overall, the code is nonsense. Where did you get it from?
it's making a pointer to a function with no arguments
Rather, it is making a pointer to a function with obsolete style parameter list.
But wtf is the second doing?
It assigns the function pointer to point at address 1000 (decimal), my means of a cast from int to the function pointer type.
why does it cause an error when I try to call the function: 'function()'?
Likely because there is no such function allocated at address 1000. You might not even have access to that area etc.
learning function pointer is pain in ass.
simple example maybe help for better understand.
suppose you want point to this function:
int sum (int a , int b) {
return a+b;
}
so you need define a pointer with same type:
int *pointerToSum (int, int);
and simply assign it to function:
pointerToSum = ∑
if you want use it:
(*pointerToSum)(3, 5); //8
you can use function-pointer tag to find out more complex answers.
your question delete by people because there is duplicate question asked before.
I implement function-pointer for myself and it's a little complex and you can see in : exercise of function pointer
I wish you the best.

Why function call only pass the first argument

I'm trying to call a function (on line 15) just via a cast but only the first argument is getting passed, how could I fix it?
I tried to change the float value "2" to 2.0f to declare it's a float and not an int but it's still not working.
!Note that the code is horrible because it's a code golf, the line 15 has to be in a dll form later, this code here is just a test program to avoid launching the target process multiples times. Here's my actual code with a score of 58 chars
DllMain(a,b,c){((int(*)(int,float))927309216)(‭7903472‬,2);}
#include <Windows.h>
#include <stdio.h>
char * sSkelModelStencil = "SkelModelStencil"; //here I reproduce the char like it is in the memory
void SetConsoleFloat(const char *sKey, float fVal) //this is the reproduction of SetConsoleFloat in CShell.dll
{
printf("arg1: %s arg2: %f\n", sKey, fVal); //printing the arguments getting passed into the function
return;
}
int main()
{
while (1) {
SetConsoleFloat("SkelModelStencil", 2); //calling the reproduction function
((int(*)())SetConsoleFloat)(sSkelModelStencil,2); //calling the reproduction function via a cast & using SetConsoleFloat addr
system("PAUSE");
}
}
In some architectures, the way arguments are passed depends on the way they're declared. For instance, special registers may be used for float parameters. It's the declaration of the function type that matters, not the declaration of the argument expression.
The parameter signature () is different from (const char *sKey, float fVal), and as a result the fVal argument is being passed differently from the way the function expects to receive it.
First of all - this is atrocious code, don't do that.
Secondly - compile your code with compiler warnings on, so the compiler can tell you where you might be going wrong. Of course, you need a proper C compiler (which MSVC is not, in case you were using that). gcc will tell you:
a.c:15:10: warning: function called through a non-compatible type
But, to answer your question: You're casting into the wrong type of function: You're using the function type void (); but you need void (const char*, float). So, try:
((void(*)(const char*, float))SetConsoleFloat)(sSkelModelStencil,2);
instead of your existing line 15. It's also a good idea to separate casts from type definitions of functions - for clarity - so you would have:
typedef void (*scf_function_t)(const char*, float);
earlier, and then:
((scf_function_t) SetConsoleFloat)(sSkelModelStencil,2);
but again - there's really no good reason to do any of this in the first place.

I keep getting this error: pointer value used where a floating point value was expected

I already saw a question about it, more than one, but it did not really solve my problem. The code is bigger, but the problem is with this part. I have this thing:
int globalx=12;
int globaly=10;
void Function (int measurex, int measurey)
float thingx()
{
(((globalx/2)-measurex)/(globalx/2));
}
float totalx=globalx/(float)thingx;
float totaly=globaly/2;
and there is something wrong with it that returns that error. globalx and globaly are,as the name suggests, two global variables. What am I doing wrong here? How can I write something that does what I do intend to do here?
A couple of things about your code:
Replace thingx with thingx().
Function definition should be inside braces {...}.
Define thingx() outside Function definition (compiler dependent, since Nested functions are not allowed in standard C).
Add a return statement to the thingx() function.
Add int measurex as an argument to thingx() function.
In Function, after getting the values of totalx and totaly you are not doing anything with them (maybe you just didn't put the whole code of this function in your question).
Your functions definitions should look like this:
float thingx(int measurex)
{
return (((globalx/2)-measurex)/(globalx/2));
}
void Function (int measurex, int measurey) {
float totalx=globalx/(float)thingx(measurex); // <-- missing parentheses, should be thingx(...)
float totaly=globaly/2;
// You probably want to do something with totalx and totaly here...
}
main:
int globalx=12;
int globaly=10;
Function(globalx, globaly);
Also, keep in mind that this will truncate the result to an integer globaly/2 since globaly is defined as int (You can read this about integer division:
What is the behavior of integer division?)
The error you're seeing, because, thingx() being a function, thingx is basically a function pointer, and you're trying to perform the division of a float with a function pointer.
First, let me declare clearly, Nested functions are not standard C. They are supported as GCC extension..
Having said that, in your case, you need to
Move the thingx() function definition outside of Function().
Just like you did for thingx() function, the body of Function() should also be inside {...}.
Use the function call operator () to call a function. So basically your statement should look like
float totalx=globalx/(float)thingx(measurex);
ad the function definition should look like
float thingx(int measurex){..
Add a return statement to your function. As per the C11 standard, chapter §6.9.1
If the } that terminates a function is reached, and the value of the function call is used by
the caller, the behavior is undefined.
so, the function body should look like
{
return (((globalx/2)-measurex)/(globalx/2));
}
Your code is really messed up. For your function you need to have all your code inside of braces {}. Like this...
void myFunction(int a, int b)
{
//put your code in here
}

Strange float? Pointer to a float in a struct

first time posting here
I'm currently porting some code for an embedded device. Basically getting everything to work with a new compiler (AVR-GCC) from an out-of-date existing proprietary compiler
I've come across this strange looking (to me anyway!) variable in a struct. I can't work out what it is with the parentheses. It is in a struct which is used for raw values:
float (*tc)( float value );
My IDE highlights 'value' as a compiler keyword, just like 'float' so I don't know if this is AVR-GCC specific?
This is then used in a function which has a float argument called 'reading' and it tries to return the following:
return (raw[rCN3].tc)( reading );
The line above actually causes the program to attempt to access out of bounds memory.
I haven't seen code like this before so was wondering if anyone could help me decipher it? It worked with the old compiler but is causing a problem with AVR-GCC
Thanks in advance. Alex
This is a function pointer. It points to a function that returns a float value and that has a float parameter.
Two things:
1) float (*tc)( float value ) is a function pointer to a function taking a float as a parameter, returning a float
2) 'value' is a keyword in C# and may also be in other languages; hence its highlighting. Check your editor language settings.
That is a function pointer variable.
tc is a pointer to a function, which takes a single float as argument and returns a `float.
The reason it accesses out of bounds memory is probably because rCN3 is out of bounds for the array raw.
That is a function pointer.
It means that tc holds the address of a function accepting a single float argument, and returning a float value.
For instance, you could set it to the standard library's sinf function, like so:
somestruct.tc = sinf;
somestruct.tc(3.14159265f / 2); /* This will return roughly 1.0f. */
Also, the ever-useful cdecl says:
declare tc as pointer to function (float) returning float

Set a function pointer to a static address

I'm injecting a DLL into another process and want to call a function that is in that binary based on it's address (0x54315).
How can I actually declare a function, and then set it to this address?
#define FUNC 0x54315
void *myFuncPtr;
int main()
{
myFuncPtr = FUNC; // pretty sure this isn't how
myFuncPtr(); // call it?
}
The existing answers work, but you don't even need a variable for the function pointer. You can just do:
#define myfunc ((void (*)(void))0x54315)
and then call it as myfunc() just like you would an ordinary function. Note that you should change the type in the cast to match the actual argument and return types of the function.
You need to define myFuncPtr as a function pointer, a void* isn't callable.
Best to use a typedef for that:
typedef void (*funptr)(void);
funprt myFuncPtr;
(Assuming your function takes nothing and returns nothing.)
Then you'll get a warning on the assignment - use a type cast to "silence" it, since this is indeed what you need to do.
You're pretty much on your own with this though, if the signature doesn't match, the calling convention is wrong, or the address is wrong, the compiler cannot validate anything and you get to pick up the pieces.
Your code should work once the syntax is corrected to actually be a function pointer. I failed to read it properly for my first version of this answer. Sorry.
As stated by Mat, the proper syntax for a function pointer would be:
void (*myFuncPtr)(void) = (void (*)(void)) FUNC;
This is often simplified by using a typedef since the C function pointer syntax is somewhat convoluted.
Also, you're must be really sure the function to be called is at that same exact address every time your injected DLL runs. I'm not sure how you can be sure of that, though ...
Also, you would need to pay attention to the calling conventions and any arguments the function at FUNC might be expecting, since if you get that wrong you will likely end up with stack corruption.

Resources