Passing pointer to a function - c

//old and auqHdr are data structures of type gblAuqEntry and auQ respectively
//I traverse through the list 'auqHdr' and when I match the element 'old', I need to remove it
removeAUfromNodeAUQ(&old, &auqHdr);
//Function implementation
static void removeAUfromNodeAUQ(gblAuqEntry *old, auQ *auqH)
{
auQ *auqPtr, *prev;
int found =0;
for (auqPtr = auqH; auqPtr; auqPtr = auqPtr->nxt)
{
if (something)
prev = auqPtr;
else
{
prev->nxt = old->nxt;
found = 1;
break;
}
}
I am trying to remove the element 'old' in the list 'auqHdr'.
The error I am getting is "declaration is incompatible with previous "removeAUfromNodeAUQ""
Can someone please point out what I am doing wrong here?
Thanks

If you call the function before declaring it, C implies a return type of int, not void.
You should add this declaration in the header or at the top of your file to address the problem:
static void removeAUfromNodeAUQ(gblAuqEntry *old, auQ *auqH);

Well, if your code is exactly as you posted, then this:
removeAUfromNodeAUQ(&old, &auqHdr);
Is not a function call, it is a function declaration. You then define it, but with a different signature. In that context you are forward declaring a function. C assumes a return type of int for you.

Related

Is it possible to modify the content of a struct pointer inside a function?

I am C begginer, I was trying to create a function that modify the content of a struct pointer, but it couldn't make it, instead, the content remains the same.
Here my code:
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int age;
int code;
}person;
void enter(person *struct_pointer);
void main(void)
{
person *person_1 = NULL;
enter(person_1);
printf("CODE: %i\n", person_1->code);
free(person_1);
}
void enter(person *struct_pointer)
{
struct_pointer = malloc(sizeof(*struct_pointer));
struct_pointer->age = 10;
struct_pointer->code = 5090;
}
In the example above when I print code of person_1 it does not print nothing, so I assume is because person_1 is still pointing to NULL.
Can someone pls explain how can I do this, and if it cannot be made why.
Thanks
To change an object (pointers are objects) in a function you need to pass it to the function by reference.
In C passing by reference means passing an object indirectly through a pointer to it. Thus dereferencing the pointer the function has a direct access to the original object.
So your function should be declared and defined the following way
void enter(person **struct_pointer)
{
*struct_pointer = malloc(sizeof(**struct_pointer));
if ( *struct_pointer )
{
( *struct_pointer )->age = 10;
( *struct_pointer )->code = 5090;
}
}
and called like
enter( &person_1 );
Otherwise in case of this function declaration
void enter(person *struct_pointer);
the function will deal with a copy of the value of the passed pointer and changing the copy within the function will not influence on the original pointer.
Pay attention to that according to the C Standard the function main without parameters shall be declared like
int main( void )
You can modify the contents of the struct. It doesn't work for you because you are creating a new struct in the enter function rather than editing the original. Just remove the first line (the one with malloc) and instead allocate the struct in the declaration of the person_1variable.

Sending a dummy variable to a function as a compound literal

Let's say I have the following I'm using to call a function:
Item dummy;
while (!QueueIsEmpty(pq))
DeQueue(pq, &dummy);
Is there a way to put the dummy parameter into the call itself? Something like:
while (!QueueIsEmpty(pq))
DeQueue(pq, &(Item)NULL);
It looks like the method dequeues an object and copies its value to the dummy variable. Where would you expect it to be copied without providing a place to copy it to?
Do you want to just throw it away and clear the queue this way?
If so I would expect that you have to pass it inside unless there is another method that just clears the queue without even copying it. Maybe some clear method.
This isn't valid C [AFAICT]
From my top comment, you might mean: DeQueue(pq,(Item *) NULL) or simply: DeQueue(pq, NULL)?
You're trying to create a compound literal, but it's being initialized from a [NULL] pointer.
Here's the test program I created:
#include <stdio.h>
typedef struct {
int x;
} Queue;
typedef struct {
int y;
int z;
} Item;
int
QueueIsEmpty(Queue * pq)
{
return 0;
}
void
DeQueue(Queue * pq, Item * item)
{
}
int
main(void)
{
Item dummy;
Queue *pq = NULL;
while (!QueueIsEmpty(pq))
DeQueue(pq, &dummy);
// Is there a way to put the dummy parameter into the call itself?
// Something like:
while (!QueueIsEmpty(pq))
DeQueue(pq, &(Item) NULL);
return 0;
}
Here's the output of gcc:
x.c:38:3: error: conversion to non-scalar type requested
Here's the output of clang:
x.c:38:16: error: used type 'Item' where arithmetic or pointer type is required
What you may have wanted is:
DeQueue(pq, &(Item) { 0 })
But, passing that is a bit of [too much] trickery.
Personally, I've never done something like that. I've always just passed down a NULL pointer.
If you do really want a "dummy" parameter, I'd do the Item dummy; thing [vs the compound literal]. It's actually faster because you don't add the overhead of the initialization.
To me, the compound literal is getting "too cute"
If the function requires the address of a valid object, you can pass in the address of a compound literal:
DeQueue(pq, &((Item){0}) );

C - How to pass _self into a function thats assigned to a pointer

I'm probably getting mixed up as I'm a OO developer. I'm trying to have several instances that call a common method.
I want to somehow reference the caller in a function that is assigned thus...
header
typedef struct _Part Part;
struct _Part {
void (*move)();
}
code
void move(Part p) {
}
void main() {
Part part1;
part1.move = move(part1); <-- Won't compile
part1.move();
}
Is there some way of making this work or do I have to stop thinking like an OO dev and just call the move method directly, passing in the instance?
Declare the structure like
typedef struct _Part Part;
struct _Part {
void (*move)( Part);
};
and just write
part1.move = move;
The function designator is implicitly converted to a pointer to the function.
And then write
part1.move( part1 );

How to fix errors in function returning pointer pointing to a structure data

I am trying to access data in the structure type function through a pointer. When i do it, i am getting 3 errors
#79 expected a type specifier
#159 declaration is incompatible with previous "memcmp"
Header file:
typedef struct
{
uint8 a[50];
uint8 b;
uint8 c;
} get;
.c file:
main.c()
{
get example[3];
get* example(void)
{
uint_8 l_LoopCounter_u8;
example1_st.a[l_LoopCounter_u8++] = data;
example.b = data;
example.c = data;
return (void*)&example1_st ;
}
}
Here is code which fixes the errors you ask about and a few others.
Without a MCVE it is hard to get it completely working.
You have some design changes coming up, to make the function work on any kind of variable, not only globals.
Making a nested function is not a good way to make a local variable accessable in a funciton. Get the code working on a global, then change to work on call-by reference variables.
The ++ indicate a more complex plan you are following. Do that later.
get example1_st[3]; // changed to the obviously intended name,
// should fix 'declaration is incompatible with previous "memcmp"'
// made this a global, to keep it accessable from function,
// make the code work, then refactor to have the function work on
// variables via call-by reference parmeters
// avoid nested function definition
get* example(void)
{
uint_8 l_LoopCounter_u8=0; // init index variable
example1_st.a[l_LoopCounter_u8] = data; // removed ++, which is unnclear/risky here
example1_st.b[l_LoopCounter_u8] = data;
example1_st.c[l_LoopCounter_u8] = data;
return &example1_st ; // no need to cast to void, type is correct
}
int main(void) //changed to a correct main function head,
// should fix "expected a type specifier"
{
// note that your main function was functionally empty anyway...
}
Note:
No, I did not test this code. It would be hard for lack of a MCVE by OP.
This is meant to help with problems, not deliver working code for unknown purpose.

Fill function pointer array in external files (C)

I have been struggling with function pointers for some time now. Maybe you guys can help me out.
In my project I have multiple functionalities for the same device and each functionality is written in its own .c file. The generic functionalities (which apply to all device functions) are written in generic.c.
I would like to create a function pointer array in the generic c file and fill that array in the other function files. So I can call the right function based on a device function identifier in the generic file.
What I have right now:
// in generic.h:
typedef void (*func_ptr_t[])(arguments);
extern func_ptr_t devFunctions[3];
And I would like to:
// in function1.c:
#include "generic.h"
devFunctions[1] = &functionName;
But then it complains about a type specifier missing AND the array initializer must be a list. If I add the type like
func_ptr_t devFunctions[1] = &functionName;
I get an error about an incomplete element type 'func_ptr_t'.
I can't initialize the entire array list from one file since it is filled from multiple files.
Anybody got an idea on how to tackle this?
Thanks!
-edit-
Because you can't use statements outside of functions I've changed my application. Now it does not use an array anymore and it updates the function pointer in the generic.c upon calling the specific function file.
So the end result:
In generic.h:
typedef void (*func_ptr_t)(<function arguments>)
In generic.c:
func_ptr_t devFunction;
In function1.c:
#include "generic.h"
extern func_ptr_t devFunction;
void functionToBeCalledFromMain( void ){
devFunction = functionName;
}
void functionName (void ){
// Function to be called from generic.c via function pointer
}
As most of you pointed out, filling the array is a statement which can't be put outside a function (duh...). So what I wanted is not really going to work in this case. I rewritten my application to update a function pointer (not an array anymore) on every run with the function I need. Saves a lot of trouble :)
Thanks guys!
For an example about functions of the type int f(int);, you can check :
/* function definition */
int functionName(int arg)
{
/* do things */
return arg * 2;
}
/* create the type "function pointer int->int" */
typedef int (*func_ptr_t)(int);
/* create the array */
func_ptr_t devFunctions[3];
int main(void)
{
/* associate the good function */
devFunctions[0] = &functionName;
/* call it with an arg */
return devFunctions[0](42);
}
Putting the above comments together, you probably wanted
typedef void (*func_ptr_t)(arg_type_list);

Resources