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
Related
I am calling a DLL from C, but when I call GetProcAddress, GCC says:
warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
The DLL takes a pointer to a double array and returns a pointer to a double array. Here is the relevant part of the C code:
typedef double* (*dllfunc1)(double*);
double *return_pointer;
hinstLib = LoadLibrary(dllname);
dll_handle = GetModuleHandle(dllname);
return_pointer = (dllfunc1)(GetProcAddress(dll_handle, "Main_Entry_fn"));
The final line is the one that fails. I have tried a number of different permutations, but none has worked. There is a fair amount of info on the net about typedef prototypes for function pointers, but very few in the context of GetProcAddress to call a DLL function.
When I change the definition of return_pointer to:
int return_pointer
I get:
warning: assignment makes integer from pointer without a cast
So it looks like the problem is in the variable "return_pointer." Most likely it needs to be defined as int and cast to a pointer, but I haven't been able to cast it to a pointer. The original definition (*double) was because it returns a pointer to a double array.
Where am I going wrong? Any ideas will be very much appreciated. Thanks.
I believe your code should be like this:
typedef double *(*dllfunc1)(double *);
HANDLE dll_handle = LoadLibrary(dllname);
dllfunc1 Main_Entry_fn = (dllfunc1)(GetProcAddress(dll_handle, "Main_Entry_fn"));
double *result = Main_Entry_fn(argument);
dllfunc1, which is a pointer-to-function type, is the correct type for the pointer-to-function variable that will hold the pointer returned by GetProcAddress. double * is just the type of the pointer returned by Main_Entry_fn, so that's the right type for the variable that holds the result of actually calling Main_Entry_fn.
Also, if I'm reading MSDN correctly, you do not need to call both LoadLibrary and GetModuleHandle; one or the other is enough.
Also also, it will be less confusing if you name the pointer-to-function after the function you're looking up by name.
Also also also, pointer asterisks bind to the right, so never cuddle them to the left, even if you're writing C++.
I was recently browsing for some examples to revisit C and came across a code where OP declared a variable as:
float Get_TMP007_Data();
What do the parenthesis in the variable name imply since this is not an array declaration?
That's not a variable, that's a function prototype. A common requirement (depending on the structure of your code/files) in gcc is to have them.
They're basically just the function header of a function you have written something else, something used for the pre-processor to determine what functions are being used/written. What you have there is a function called Get_TMP007_Data() that returns a float
float Get_TMP007_Data(); is a function declaration.
It is a declare Get_TMP007_Data as function returning float.
As a declaration of a function, there is no information as to what paremters should be passed. It could be used as
float f1 = Get_TMP007_Data();
float f2 = Get_TMP007_Data(42);
A better function declaration would list the parameters to be passed - perhaps even none as in:
float Get_TMP007_Data(void);
What is the proper C syntax for a function returning pointer to another function (which again may return a pointer to some thrid function etc)? I know that we can define a function as a local variable inside another function (but we need to know the address or it is useless):
int*(*a)(int) = (void*)0;
This is local variable a which represents a function which has int as a parameter and returns pointer to int, while the address of the function is 0. How can I have a function which returns, instead of pointer to int, a pointer to a function requiring char as a parameter and returning a pointer to int? This is what I've tried:
int*(*)(char)(*a)(int) = (void*)0;
But, it is a syntax error. Is there a way to do it, or maybe, the only way is to return void* and then to cast it again to function?
Edit
I am not looking only for a solution which works. I know it can be done using typedef or just by returning a generic pointer and then casting to another function. But, I am writting a code highlighter for C and I want to cover all cases which are defined by ISO C, so I am wondering does ISO C allow double returning functions, if yes, what is the proper syntax, if no, can it be found somewhere in documentation?
You could use typedefs to simplify this (and make sure you can actually understand the code a week later):
typedef int*(*FuncA)(int);
typedef FuncA(*FuncB)();
FuncB a = (void*)0;
Obviously use more descriptive names than I have done here.
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.
This question already has answers here:
Assigning Float Pointers in C [closed]
(3 answers)
Closed 9 years ago.
I'm new to C, and I'm writing a very basic function that takes an integer pointer as a parameter. Inside the function, a float pointer must be created. This function must assign the value of the integer pointer to the float and then return the float. Here's my code at the moment:
float * function(const int *x)
{
float *p = (float*)x;
return p;
}
But this results in an error that reads as such when run: "free(): invalid pointer: 0x00007fffc0e6b734". Suffice it to say, I'm very confused. Any insights you can offer would be much appreciated!
Being new to C, are you familiar with the scope of variables? (Part of) the short version of variable scope is that if you don't do a little something extra, a variable created in a function only exists inside that function. Why that's important to you: if you return a pointer to a variable that you created inside a function (without doing that little something extra) that pointer will point to an area of memory that may or may not contain the value that you assigned to it. One way to do what you want is this:
float *makefloat(int *x) {
// static keyword tells C to keep this variable after function exits
static float f;
// the next statement working from right to left does the following
// get value of pointer to int (x) by dereferencing: *x
// change that int value to a float with a cast: (float)
// assign that value to the static float we created: f =
f = (float) *x;
// make pointer to float from static variable: &f
return &f;
}
In general I seem to see more functions that accept a pointer to the variable that is to be modified, then in that function the new value is created and assigned to the area in memory referenced by the pointer. Because that area of memory exists outside of the scope of the function, there is no need to worry as much about scope and static variables. Another cool thing about static variables is that the next time the function is called, the static variable has the same value it did when the function last exited. Explained on Wikipedia.
Good explanation of * and &: Pointers in C: when to use the ampersand and the asterisk
Your function only performs a pointer conversion. A function call of the form
q = function(p); /* p is a "const int *" pointer,
q is assignment comaptible with "float *". */
can be replaced by the expression:
q = (float *) p;
by itself, this doesn't do any harm. The problem is elsewhere in your program.
Note that most type punning, like accessing an object of type int using an expression of type float via pointers, is undefined behavior in the C language. This isn't going on in the example code, but things are headed in that direction; the pointer is probably being prepared for carrying out type punning.
Consider that int and float don't necessarily even have the same size; and that is not the only consideration. In code like this:
int i = 42;
/* now treat i as a float and modify it sneakily */
*((float *) &i) = 3.14;
printf("i = %d\n", i);
the output of the printf can still be 42. The optimizing compiler can put i into a machine register, whereas the sneaky assignment might be performed on the memory location that serves as the "backing storage" for i, and so i appears unchanged since the printf call uses the register-cached copies. The compiler is not required to consider that a modification of an object designated by the type float might affect the value of an object of type i (even if they otherwise have the same size, so there is no collateral damage done by the assignment, like overwriting other objects).
In the real world, sometimes it is necessary to write a code that manipulates floating-point objects as if they were integers: typically unsigned int integers, to gain access to the bitwise representation of the float. When this is done, you have to use unions, or perhaps compiler-specific features, like GCC's -fno-strict-aliasing option which causes the compiler to optimize more cautiously in the face of type punning. in that kind of code, you make sure that the assumptions are all warranted about the sizes of types and such, with #ifdef-s for different platforms, perhaps based on values pulled from running configured scripts to detect platform features.
Needless to say, this is not a good way to be learning C at a beginner level.