What does the usage of `(void)struct_pointer`? - c

I am now reading a project and find some of the codes hard to understand, like below:
struct mcachefs_metadata_t* mdata_root;
...
mcachefs_metadata_release(mdata_root);
And the definition of mcachefs_metadata_release is as below:
void
mcachefs_metadata_release(struct mcachefs_metadata_t* mdata)
{
(void) mdata;
mcachefs_metadata_unlock ();
}
And the definitioin of mcachefs_metadata_unlock is as below:
#define mcachefs_metadata_unlock() mcachefs_mutex_unlock ( &mcachefs_metadata_mutex, "metadata", __CONTEXT );
Then, the mcachefs_mutex_unlock function:
void
mcachefs_mutex_unlock(struct mcachefs_mutex_t* mutex, const char* name,
const char* context)
{
int res;
...
mutex->owner = 0;
mutex->context = NULL;
res = pthread_mutex_unlock(&(mutex->mutex));
if (res == 0)
{
return;
}
...
}
I could not understand what does the (void) mdata; mean in the
mcachefs_metadata_release function. What does the usage of it?

It's for suppressing unused argument: mdata compiler warnings. Rather bad practice, by the way.

Related

Reuseable function for looping [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 1 year ago.
Improve this question
Question:
I want to create a reusable function, because in my code much line that use same code structure
The code using for example if { if { `Only here's the different` } }. Of course the pattern not same as this, this using as an example.
I've been code using framework such as Laravel, there's a directive called as SLOT
Is there any way I can inject code in the middle of for loop? Or anything same as SLOT inside C programming
Sample code:
void functionname() {
for (int i=0; i < total_count; i++) {
SELECT THE ITEM (i)
if (a == b) return;
if (c) {
CODE INJECT HERE
}
}
}
Forget to mention before, a, b, c and so on from the coding above is getting from ITEM (i)
You should use a callback. i.e. you should send a function pointer (i.e. the address of the function you want to execute) and use that pointer to execute that function inside your loop.
In the example below, p is a pointer to a function taking a const char * for a parameter and returning an int.
int (*p)(const char *s) ;
NB: all functions passed as parameter, to be used as callback must have the same prototype (which is why such functions are often declared taking a generic pointer parameter void * to accept whatever you've got to send to the function).
So with your example and with functions taking void * as a parameter and returning void *, and with param defining a parameter that you want to feed to your function, this gives us the following code:
void functionname(void *(*func)(void *)) {
for (int i=0; i < total_count; i++) {
SELECT THE ITEM (i)
if (a == b) return;
if (c) {
func(&param);
}
}
}
you can call your function wiht whatever function respecting the prototype... For instance:
void *my_custom_function(void *param) {
...
}
...
functionname(my_custom_function);
...
As suggested in the comment by KamilCik, use function pointers:
void functionname(void *fx)(void)) {
for (int i=0; i < total_count; i++) {
SELECT THE ITEM (i)
if (a == b) return;
if (c) {
//CODE INJECT HERE
fx();
}
}
}
And use it like
void foo(void) { puts("foo() called"); }
void bar(void) { puts("bar() called"); }
int main(void) {
functionname(foo);
functionname(bar);
}
For a concrete example:
#include <stdio.h>
int a = 1;
int b = 2;
typedef void (*selector)(int, int *);
typedef void (*injector)(void);
void select1(int x, int *c) { printf("%s: %d\n", __func__, *c = x); }
void select2(int x, int *c) { printf("%s: %d\n", __func__, *c = x); }
void inject1(void) { printf("%s\n", __func__); }
void inject2(void) { printf("%s\n", __func__); }
void
functionname(size_t total_count, selector SELECT_THE_ITEM,
injector CODE_INJECT_HERE )
{
for (size_t i=0; i < total_count; i++) {
int c;
SELECT_THE_ITEM (i, &c);
if (a == b) return;
if (c) {
CODE_INJECT_HERE();
}
}
}
int
main(void)
{
functionname(2, select1, inject1);
functionname(3, select2, inject2);
}
You can do what you ask by defining your "CODE INJECT HERE" as the body of a function, and passing a pointer to that function:
void functionname(void (*inject)(void)) {
for (int i=0; i < total_count; i++) {
SELECT THE ITEM (i)
if (a == b) return;
if (c) {
inject();
}
}
}
void do_something(void) {
CODE INJECT HERE
}
void do_something_else(void) {
OTHER CODE INJECT HERE
}
int main(void) {
functionname(do_something));
functionname(do_something_else));
}
Do note, however, that this is not simple code injection in the same sense as a macro would provide. In particular, the executions of do_something() and do_something_else() will not see the local variables of main() or of functionname(), and the do_* functions can return only from themselves, not from a caller further up the chain. The former can be mitigated to some extent by passing parameters to the do_* functions (which they must be prepared to accept).
Another alternative would be to use a macro instead of a function to provide the common framework. It would look something like this:
#define frame_it(x) do { \
for (int i=0; i < total_count; i++) { \
SELECT THE ITEM (i) \
if (a == b) return; \
if (c) { \
x \
} \
} \
} while (0)
int main(void) {
frame_it(
CODE INJECT HERE
);
frame_it(
OTHER CODE INJECT HERE
);
}
That keeps the CODE INJECT HERE code in the function using it, which might be advantageous if in fact each such piece of code is used in only one place. It also allows both that code and the framing code to access the local variables of the function in which they appear, and to return from that function if desired.
However, macro programming has earned a mostly-deserved reputation for being error prone and difficult to read and debug. Your particular need may be one that is well served by this approach, but do not choose this direction lightly.
Function pointers are great for this. You can typedef the function signatures you'd like to support. Example:
/* A signature for condition checking functions, taking a "void*" argument
and returning true or false */
typedef bool(*cond_check_t)(void*);
/* A signature for functions to execute if a condition is met. This takes a
"void*" argument but you decide what you need */
typedef void(*exec_t)(void*);
You can package these two in a struct to form a nice pair:
typedef struct {
cond_check_t checker;
exec_t executor;
} check_exec_t;
And with that, another struct to keep a bunch of these condition and executor pairs:
typedef struct {
size_t size;
size_t capacity;
check_exec_t *conditionals;
} cond_pack_t;
You then create support functions for adding checkers and executors and a function to processes one of these packaged checkers and executors.
cond_pack_t* cond_pack_create(size_t capacity) {
cond_pack_t* cp = malloc(sizeof(*cp));
if(cp) {
cp->conditionals = malloc(sizeof(*cp->conditionals) * capacity);
if(cp->conditionals) {
cp->size = 0;
cp->capacity = capacity;
} else {
free(cp);
cp = NULL;
}
}
return cp;
}
void cond_pack_destroy(cond_pack_t *cp) {
free(cp->conditionals);
free(cp);
}
bool cond_pack_add(cond_pack_t *cp, cond_check_t checker, exec_t executor) {
if(cp->size == cp->capacity) return false;
cp->conditionals[cp->size].checker = checker;
cp->conditionals[cp->size].executor = executor;
++cp->size;
return true;
}
void cond_pack_process(cond_pack_t *cp) {
for(size_t i = 0; i < cp->size; ++i) {
if(cp->conditionals[i].checker(NULL)) { /* execute checker */
cp->conditionals[i].executor(NULL); /* execute executor */
}
}
}
With that, a usage example could look like this
//---
bool some_check(void *foo) {
return true;
}
void some_executor(void *foo) {
printf("some_executor\n");
}
bool some_other_check(void *foo) {
return false;
}
void some_other_executor(void *foo) {
printf("some_other_executor\n");
}
int main() {
cond_pack_t *cp = cond_pack_create(10);
if(cp) {
cond_pack_add(cp, some_check, some_executor);
cond_pack_add(cp, some_other_check, some_other_executor);
cond_pack_process(cp); /* run all the checkers / executors */
cond_pack_destroy(cp);
}
}
Demo

Does libxml2 (C API) provide a way to remove a registered set of xmlOutputCallbacks, without removing ALL registered output callbacks?

I am working on a custom I/O layer for libxml2 and have come across an oddity in the de-registration of Output callbacks. There appears to be no way to remove just one set of output callbacks. Am I missing something? I can provide a working example if the following pseudo-code does not clarify the question.
static int _in_matcher(const char* URI) {...}
static void* _in_opener(const char* URI) {...}
static int _in_reader(void *ctxt, char *in_buf, int buf_len) {...}
static int _in_closer(void *ctxt) {...}
int test_input_callbacks(const char *file_name)
{
int handler = xmlRegisterInputCallbacks(
_in_matcher,
_in_opener,
_in_reader,
_in_closer,
);
...
xmlDocPtr doc = xmlParseFile(file_name);
xmlFree(doc);
...
xmlPopInputCallbacks();
}
static int _out_matcher( const char *URI) {...}
static void* _out_opener( const char *URI) {...}
static int _out_writer( void *ctxt, const char *out_buf, int buf_len) {...}
static int _outcloser( void *ctxt) {...}
int test_output_callbacks(const char *file_name)
{
int handler = xmlRegisterOutputCallbacks(
_out_matcher,
_out_opener,
_out_writer,
_out_closer,
);
...
int result = xmlSaveFormatFileEnc(URI, doc, NULL, 0);
xmlFree(doc);
...
/* There does not appear to be a function that
* removes _only_ the last output callbacks
* registered!
*/
==> ?? xmlPopOutputCallbacks() ?? <==
}
As a work around, I added this function to my [local] version of libxml2 (2-2.9.10):
int
xmlPopOutputCallbacks(void)
{
if (!xmlOutputCallbackInitialized)
return(-1);
if (xmlOutputCallbackNr <= 0)
return(-1);
xmlOutputCallbackNr--;
xmlOutputCallbackTable[xmlOutputCallbackNr].matchcallback = NULL;
xmlOutputCallbackTable[xmlOutputCallbackNr].opencallback = NULL;
xmlOutputCallbackTable[xmlOutputCallbackNr].writecallback = NULL;
xmlOutputCallbackTable[xmlOutputCallbackNr].closecallback = NULL;
return(xmlOutputCallbackNr);
}
It works, but I get the nagging feeling there is either something I am missing; or there is a valid reason why libxml2 does not provide the ability to remove individual sets of output callbacks.
Any help/advice would be greatly appreciated!
Thanks,
Tom

CreateThread wrapper function

I am currently working on a project where we have a C thread implementation for UNIX systems using pthreads. Now we want to be able to run this entire project on Windows as well, and I am translating all the threading for WIN32. Now I encountered a problem for which I could not come up with a decent solution.
I have the thrd_create() function:
static inline int thrd_create(thrd_t *thr, thrd_start_t func, void *arg) {
Args* args = malloc(sizeof(Args));
args->arg = arg;
args->function = func;
*thr = CreateThread(NULL, 0, wrapper_function, (LPVOID) args, 0, NULL);
if (!*thr) {
free (args);
return thrd_error;
}
return thrd_success;
}
This function is supposed to create a new thread, and the user provides a start function. For convenience, I would like to leave the implementation that calls thrd_create() untouched if possible. For this reason, I created a wrapper_function:
static inline DWORD wrapper_function(LPVOID arg) {
Args * args;
args = (Args*) arg;
DWORD res = args->function(args->arg); //This does obviously not work
return res;
}
My question is: What DWORD should my wrapper function return? The function provided by the user for the pthread implementation has void return type, so I won't get any result from that. Any suggestions?
EDIT
Args looks like this:
struct Args {
void (*function)(void * aArg);
void* arg;
};
typedef struct Args Args;
According to manuals it is better to stick to a correct signature and use return value:
Windows
Pthreads
The other matter of concern would be the lifetime of args, I'd say the best way is for a caller to clean up, so they need to be tracked with your thread until it terminates.
An approximate API could be something along the lines of the following:
/* Your general error codes enumeration
* which should probably reside in a general
* header
*/
typedef enum {
OK = 0,
// Your application specific error codes
} error_t;
#ifdef _WIN32
#include <Windows.h>
typedef HANDLE thread_handle_t;
#else // assume pthreads
#include <pthread.h>
typedef pthread_t thread_handle_t;
#endif
typedef error_t(*entry_func_t)(void*);
typedef struct {
entry_func_t func;
void *args;
error_t _result;
thread_handle_t _handle;
} thread_t;
// returns OK(0) on success
// returns error code indicating a problem
error_t thread_create(thread_t *t);
An aproximate implementation would be:
#ifdef _WIN32
DWORD _win_entry_f(void *args) {
thread_t *t = args;
t->_result = t->func(t->args);
return 0; // Or some other Windows-specific value
}
error_t thread_create(thread_t *t) {
error_t err = OK;
if(!(t->_handle = ThreadCreate(NULL, 0, _win_entry_f, t, 0, NULL))) {
switch (GetLastError()) {
// Populate error with code
}
}
return err;
}
#else
void * _pthread_entry_f(void *args) {
thread_t *t = args;
t->_result = t->func(t->args);
return NULL; // Or some other pthreads specific value
}
error_t thread_create(thread_t *t, entry_func_t func, void *args) {
error_t err = OK;
switch(pthread_create(&t->_handle, NULL, _pthread_entry_f, t)) {
case 0: break;
// other cases populate err
}
return err;
}
#endif
Invokation would look somewhat like this.
error_t func(void* args) {
return OK;
}
.....................
thread_t t = { .func = func, .args = NULL };
thread_create(&t);
Obviously you'll need to implement your own cancelation, result collection, join, ...

"called object is not a function" error - C

int getSpeedOfMotorInPercent(int RPM)
{
int speedOfMotor = (RPM/5000.0)*100;
return speedOfMotor;
}
static char *test_GetSpeedOfMotor(int speedInPercent)
{
mu_assert("error, RPM != 70%", speedInPercent == 70);
return 0;
}
static char *run_all_tests(int RPM)
{
mu_run_test(test_GetSpeedOfMotor(RPM));
return 0;
}
I get the error "called object is not a function" on mu_run_test(test_GetSpeedOfMotor(RPM));
I tried removing the pointer of the function but then I get even more errors.
EDIT:
#define mu_assert(message, test) do { if (!(test)) return message; } while (0)
#define mu_run_test(test) do { char *message = test(); tests_run++; if (message) return message; } while (0)
extern int tests_run;
this is the mu_run_test function. It is provided to me like that in the header file.
You're passing test_GetSpeedOfMotor(RPM) as test in the macro, which will result in this code:
char *message = test_GetSpeedOfMotor(RPM)();
Since you're probably using a test framework which you don't want to change, just remove the RPM parameter from the declaration of test_GetSpeedOfMotor function and use it like this:
int testRpmInPercent;
static char *test_GetSpeedOfMotor()
{
mu_assert("error, RPM != 70%", testRpmInPercent == 70);
return 0;
}
static char *run_all_tests(int RPM)
{
testRpmInPercent = RPM;
mu_run_test(test_GetSpeedOfMotor);
return 0;
}
Then you'll have to find an other way of sharing the RPM value with the test function. Like a global variable or with whatever method the test framework has to offer.
If you're willing to change the test framework, I would modify that define to this (remove () after test):
#define mu_run_test(test) do { char *message = test; tests_run++; if (message) return message; } while (0)

Memory allocation error for structs with members that are function pointers and void pointers

I have written a straightforward C code that uses an engine to run two different algorithms depending on user input. It uses function pointers to the algorithm methods and objects. There is a nasty memory bug somewhere that I can not track down, so maybe I am allocating memory in the wrong way. What is going wrong?
Below is (the relevant parts of) a minimal working example of the code.
main.c
#include "engine.h"
int main()
{
char *id = "one";
Engine_t eng;
Engine_init(&eng);
Engine_select_algorithm(eng, id);
Engine_run(eng);
}
engine.h
typedef struct _Engine *Engine_t;
engine.c
#include "engine.h"
#include "algorithm_one.h"
#include "algorithm_two.h"
typedef struct _Engine
{
void *p_algorithm;
void (*init)(Engine_t);
void (*run)(Engine_t);
} Engine;
void Engine_init(Engine_t *eng)
{
*eng = malloc(sizeof(Engine));
(*eng)->p_algorithm = NULL;
}
void Engine_select_algorithm(Engine_t eng, char *id)
{
if ( strcmp(id, "one") == 0 )
{
eng->init = Algorithm_one_init;
eng->run = Algorithm_one_run;
}
else if ( strcmp(id, "two") == 0 )
{
eng->init = Algorithm_two_init;
eng->run = Algorithm_two_run;
}
else
{
printf("Unknown engine %s.\n", id); exit(0);
}
eng->init(eng);
}
void Engine_run(Engine_t eng)
{
eng->run(eng);
}
void Engine_set_algorithm(Engine_t eng, void *p)
{
eng->p_algorithm = p;
}
void Engine_get_algorithm(Engine_t eng, void *p)
{
p = eng->p_algorithm;
}
algorithm_one.h
typedef struct _A_one *A_one_t;
algorithm_one.c
#include "engine.h"
#include "algorithm_one.h"
typedef struct _A_one
{
float value;
} A_one;
void Algorithm_one_init(Engine_t eng)
{
A_one_t aone;
aone = malloc(sizeof(A_one));
aone->value = 13.0;
//int var = 10;
Engine_set_algorithm(eng, &aone);
}
void Algorithm_one_run(Engine_t eng)
{
A_one_t aone;
Engine_get_algorithm(eng, &aone);
printf("I am running algorithm one with value %f.\n", aone->value);
// The code for algorithm one goes here.
}
The code for algorithm_two.h and algorithm_two.c are identical to the algorithm one files.
There must be a memory bug involved, because the code runs as given, but if I uncomment the
//int var = 10;
line in algoritm_one.c the code crashes with a segmentation fault.
You pass the wrong thing to Engine_set_algorithm. You are passing the address of a local variable rather than the address of the algorithm. You need to write:
Engine_set_algorithm(eng, aone);
And also Engine_get_algorithm is wrong. You are passed a pointer by value and modify that pointer. So the caller cannot see that modification. You need it to be:
void Engine_get_algorithm(Engine_t eng, void **p)
{
*p = eng->p_algorithm;
}
I think your code would be easier if you defined a type to represent an algorithm. That type would be just a void*, but it would make the code much easier to read. What's more, I would make Engine_get_algorithm return the algorithm.
algorithm Engine_get_algorithm(Engine_t eng)
{
return eng->p_algorithm;
}
void Engine_set_algorithm(Engine_t eng, algorithm alg)
{
eng->p_algorithm = alg;
}

Resources