I've a huge C project with a module reading and managing configuration data. If I have to add a new configuration parameter, I'll have to edit several functions, e.g. as pseudo-code:
void read_configuration(config *c) {
read_param("p1", c->p1);
read_param("p2", c->p2);
read_param("p3", c->p3);
/* ... */
}
void dump_configuration(config *c) {
dump_param("p1", c->p1);
dump_param("p2", c->p2);
dump_param("p3", c->p3);
/* ... */
}
Is there a way to ensure by macro at compile time, that each location has at least the same count of parameters? I thought of making dump_param some kind of macro counting the invocations and then add something like
#if nr_read != nr_dump
#error "You forgot something, idiot!"
#endif
at the end of the module. I can't find a method to make the macro count its invocations, though...
Since the list of parameters is the same in both functions, how about factoring that out and avoid any possible mismatch ?
Using X-macros
#define X_CONFIG_PARAMS(config) \
X("p1", (config).p1) \
X("p2", (config).p2) \
X("p3", (config).p3)
void read_configuration(config *c) {
#define X(name, param) read_param(name, ¶m);
X_CONFIG_PARAMS(*c)
#undef X
}
void dump_configuration(config *c) {
#define X(name, param) dump_param(name, ¶m);
X_CONFIG_PARAMS(*c)
#undef X
}
Using function pointers
void alter_config(config *c, void(*func)(char const *name, Param *param)) {
func("p1", &c->p1);
func("p2", &c->p2);
func("p3", &c->p3);
}
void read_configuration(config *c) {
alter_config(c, read_param);
}
void dump_configuration(config *c) {
alter_config(c, dump_param);
}
Using an array and offsetof
struct param_info {
char const *name;
size_t config_offs;
};
param_info allParams[] = {
{"p1", offsetof(config, p1)},
{"p2", offsetof(config, p2)},
{"p3", offsetof(config, p3)}
};
void read_configuration(config *c) {
size_t paramCount = sizeof allParams / sizeof *allParams;
for(size_t i = 0; i < paramCount; ++i) {
Param *p = (Param*)((char*)config + allParams[i].config_offs);
read_param(allParams[i].name, p);
}
}
void dump_configuration(config *c) {
size_t paramCount = sizeof allParams / sizeof *allParams;
for(size_t i = 0; i < paramCount; ++i) {
Param *p = (Param*)((char*)config + allParams[i].config_offs);
dump_param(allParams[i].name, p);
}
}
I would rather let the preprocessor write the code in the first place.
It could look something like this:
Define the list of parameters in a separate file, say parameters.inc:
PARAM (p1)
PARAM (p2)
...
Then in the source code locally define the macro PARAM as required and let the preprocessor include and expand the contents of parameters.inc:
void read_configuration(config *c) {
#define PARAM(NAME) read_param(#NAME, c->NAME);
#include "parameters.inc"
#undef PARAM
}
void dump_configuration(config *c) {
#define PARAM(NAME) dump_param(#NAME, c->NAME);
#include "parameters.inc"
#undef PARAM
}
I don't think you can do this at compile time without ugly hacks.
What you could do: add a test to your test suite which replaces the header that contains the read_param() and dump_param() macros so they generate code which only updates a counter. Then, in the main() function of that test, place an assertion that compares both counters and fails if they're not equal.
You do have a test suite and run it at compile time, right? ;-)
However, I do agree with the comment that it's probably better to do this differently. In an approach called "table-driven programming", you turn the macro definition and data definition on their head (that is, you have the #define in your .c file and the use of the macro in the header rather than the other way around), you don't have this problem. Poul-Henning Kamp, of FreeBSD fame, explains very well how to that here.
Related
There are many functions in the C libraries that require users to input with macros.
I wonder, if I have an array of strings, with contents of macros, like so:
char s[][3] = {"SIGINT", "SIGKILL", "SIGSTOP"};
How can I pass these strings as macros? (Like so:)
signal(s[0], do_something);
with do_something is a function pointer.
(and yes, technically I can pass ints in this case, but... hypothetically, ya know?)
EDIT:
As #RemyLebeau and SGeorgiades point out, the "SIGINT",... are aliases for integer consts, and therefore can be stored in an int array, like so:
int s[3] = {SIGINT, SIGKILL, SIGSTOP};
Although SGeorgiades and Remy Lebeau already gave you the answer, here is something that I've used in the past to allow conversion and pretty printing of signal numbers and names:
#include <stdio.h>
#include <signal.h>
#include <string.h>
struct sigfun {
int signo;
const char *signame;
};
#define SIGFUN(_sig) \
{ \
.signo = _sig, \
.signame = #_sig \
}
struct sigfun siglist[] = {
SIGFUN(SIGINT),
SIGFUN(SIGKILL),
SIGFUN(SIGSTOP),
// ...
{ .signo = 0, .signame = NULL }
};
#define SIGFORALL(_sig) \
_sig = siglist; _sig->signame != NULL; ++_sig
int
signame_to_signo(const char *signame)
{
struct sigfun *sig;
for (SIGFORALL(sig)) {
if (strcmp(sig->signame,signame) == 0)
break;
}
return sig->signo;
}
const char *
signo_to_signame(int signo)
{
struct sigfun *sig;
for (SIGFORALL(sig)) {
if (signo == sig->signo)
break;
}
return sig->signame;
}
UPDATE:
why not put for into SIGFORALL? –
tstanisl
For a few reasons ...
I've done that before (e.g.):
#define SIGFORALL(_sig) \
for (_sig = siglist; _sig->signame != 0; ++_sig)
SIGFORALL(sig) {
// do stuff
}
This tends to confuse certain IDEs and/or tools that parse the code without running it through the preprocessor.
It's also more difficult for programmers to quickly (without digesting the macro) skip over it.
They don't see a for and have trouble figuring out what SIGFORALL(sig) { does.
Is the macro a wrapper for if, for, or while?
With:
#define SIGFORALL(_sig) \
_sig = siglist; _sig->signame != 0; ++_sig
for (SIGFORALL(sig)) {
// do stuff
}
there is a better chance they can continue around the construct because they can understand (i.e. skip over) the for (...) [syntactically] without having to know what the macro is doing. That is, nobody has to "drill down" into the macro unless they wish to.
Another reason is that without the for in the macro, we can add extra code to the for loop's initialization and iteration expressions. It's more flexible.
For example, I've used a similar macro for linked list traversal and wanted to know the index/count of an element:
#define LLFORALL(_node) \
_node = nodelist; _node != NULL; _node = _node->next
int idx;
for (idx = 0, LLFORALL(node), ++idx) {
if (node->value == 5)
printf("found value at index %d\n",idx);
}
There's no absolute rule about this. Ultimately, it's a [personal] style preference.
Perhaps what you want instead is:
int s[3] = { SIGINT, SIGKILL, SIGSTOP };
signal(s[0], do_something);
I have a function like:
typedef struct
{
bool x;
bool y;
bool z;
} myStruct;
static void myFunction(const myStruct *pTomystruct_out)
{
if (pTomystruct_out->x == TRUE)
{
/*Do Something*/
}
}
Now for some debug purpose I want to add debug code to set the pointer parameter always to TRUE.
Within the function before the if statement I want to do something like:
pTomystruct_out.x = TRUE /*This is not the correct way*/
How to do this in the right way?
Thanks!
pTomystruct_out is a pointer, so you have to dereference that for manipulating what is pointed.
You can use * opetator to dereference:
(*pTomystruct_out).x = TRUE;
Also you can use -> operator where A->B means (*A).B:
pTomystruct_out->x = TRUE;
Also, this is not enough because the pointer pTomystruct_out is marked as const.
You can use a cast to non-const pointer for having it allow modifications.
((myStruct*)pTomystruct_out)->x = TRUE;
This is syntactically collect, but it may be dangerous to modify the object that is thought not to be modified. Creating a copy of the object and modifying the copy is safer.
typedef struct
{
bool x;
bool y;
bool z;
} myStruct;
#if 1 /* debug mode */
static void myFunction(const myStruct *pTomystruct_out_arg) /* change argument name */
{
myStruct pTomystruct_debug_temp = *pTomystruct_out_arg; /* make a copy */
myStruct *pTomystruct_out = &pTomystruct_debug_temp; /* declare a variable with original argument name */
pTomystruct_out->x = TRUE; /* modify the copy */
#else
static void myFunction(const myStruct *pTomystruct_out)
{
#endif
if (pTomystruct_out->x == TRUE)
{
/*Do Something*/
}
}
As mentioned in previous answer, the parameter is const, disabling modifications to that parameter. You probably don't want it to be const.
To add debug code, you can make use of macros. You can have a header file contain macros, like seen below:
#define DEBUG
Or:
#define DEBUG 1
Included a header with this macro allows you to write your function as follows:
static void myFunction(const myStruct *pTomystruct_out)
{
#ifdef DEBUG
pTomystruct_out.x = TRUE
#endif
}
If you used the latter macro, #define DEBUG 1 (which I recommend), you can use an if-statement instead:
static void myFunction(const myStruct *pTomystruct_out)
{
#if DEBUG
pTomystruct_out.x = TRUE
#endif
}
I recommend using #define DEBUG 1, because then you don't have to comment out the macro whenever you don't want it. You can just set it to 0.
If you don't want a header file, you can use the -D flag using gcc, like gcc <INPUTFILE> -DDEBUG.
I'm working on a network service that based on commands it receives over the network, it has workers perform different jobs. I want to have a log entry for every time a certain worker is tasked with doing some job.
I have a function (say function_caller) which, among other things, calls another function which it receives its pointer as an argument. I'd like to have my logger notify what kind of function function_caller calls.
Originally I wanted the function_caller to receive some enum instead of a function pointer, provide the enum to the logger, and then use a helper function which returns a suitable pointer based on the enum. However, function_caller is already deeply tangled in the codebase I'm working on, and it looks like it would be a lot of work to refactor all the functions that call function_caller to choose the right enum and use a new argument.
So my next idea was having a switch that for every function pointer will have some string representation of, but I've never stumbled upon something like that (and struggled to find anyone even mentioning such an idea on Google), so I have a feeling I might be missing some serious downsides to this option.
The only significant problem I see is that every developer that decides to pass a new kind of function pointer to function_caller will have to somehow know to update the switch, otherwise it will fail.
Am I missing anything else? Or maybe there's some other approach I should consider?
How about something like this? Instead of a switch, store a table of functions and their name strings. The table can even be kept dynamically updated, unlike a switch case. You will not need to walk along the edge of the standard as well!
#include <stdio.h>
typedef void (*callback_t) (void);
void first (void) { printf("%d", 1); };
void second (void) { printf("%d", 2); };
void third (void) { printf("%d", 3); };
typedef struct fntable_t
{
callback_t fn;
char *name;
} fntable_t;
fntable_t fntable[] =
{
{ first, "first" },
{ second, "second" },
{ third, "third" }
};
char* log_str(callback_t c)
{
for(int i = 0; i < sizeof(fntable) / sizeof(fntable_t); i++)
{
if(fntable[i].fn == c)
return fntable[i].name;
}
return "unknown";
}
void function_caller(callback_t c)
{
printf("%s",log_str(c));
c();
}
int main(void)
{
function_caller(first);
function_caller(second);
function_caller(third);
return 0;
}
You could replace function_caller with a wrapper macro of the same name that calls the renamed function function_caller_internal which gets an additional string argument. The wrapper macro can then pass an additional stringified function name.
This works only if function_caller is always called with a function name, not a function pointer variable.
Example:
#include <stdio.h>
static void funcA(void)
{
printf("This is funcA\n");
}
static void funcB(void)
{
printf("This is funcB\n");
}
/* renamed function gets an additional string argument */
static void function_caller_internal(void (*func)(void), const char *name)
{
printf("calling %s\n", name);
func();
}
/* wrapper macro stringifies the function name to pass it the additional argument */
#define function_caller(func) function_caller_internal(func, #func)
int main(void)
{
/* unchanged calls */
function_caller(funcA);
function_caller(funcB);
return 0;
}
This prints
calling funcA
This is funcA
calling funcB
This is funcB
If you can change the API of the functions, then consider using __func__ to get the textual name of each function. If you can have a function pointer type along the lines of this:
typedef void func_t (const char** name);
Then you can have each function return its name to the caller.
void foo (const char** name)
{
/* do foo stuff here */
*name = __func__;
}
void bar (const char** name)
{
/* do bar stuff here */
*name = __func__;
}
Example:
#include <stdio.h>
typedef void func_t (const char** name);
void foo (const char** name)
{
/* do foo stuff here */
*name = __func__;
}
void bar (const char** name)
{
/* do bar stuff here */
*name = __func__;
}
const char* function_caller (func_t* func, const char** name)
{
func(name);
return *name;
}
int main(void)
{
static func_t*const func [] =
{
foo,
bar,
};
const char* name;
for(size_t i=0; i<sizeof func/sizeof *func; i++)
{
puts( function_caller(func[i], &name) );
}
}
Assuming your codebase has sane variable names and function names, you can add a char * argument to your function caller:
void function_caller(char *name, int fpnt());
and then provide a macro:
#define function_caller_autoname(fpnt) function_caller(#fpnt, fpnt)
(Or, for spaghetti code, you can provide a macro with the same name as the function).
The #fpnt will be expanded by the proceprocessor to a string literal with the function name.
Then when your codebase called:
function_caller(some_function)
refactor it to:
function_caller_autoname(some_function)
# will be expanded to by the processor:
# function_caller("some_function", some_function)
or refactor it manually to provide the name/identificator/description of the function:
function_caller("Some function: ", some_function)
That way you can pass a custom string that describes the function along with the pointer. Also, each developer can pass a custom description string.
I have read that C does not support dynamic function calls. My program has an ever growing number of test cases implemented as separate functions like -
int testcase1(void);
int testcase2(void);
int testcase3(void);
Each time I add a new test case, I also have have to add the call to my main function like -
int main(int argc, char **argv){
assert(!testcase1());
assert(!testcase2());
assert(!testcase3());
}
I would prefer to call something like assert(!testcase*()) where * matches any string which resolves to a valid function name in my program.
Can you think of a more convenient solution?
If you all your testcases have same signature then you can use an array of function pointers:
void (*func[])() = { testcase1, testcase2 };
for (size_t i = 0; i < sizeof(func)/sizeof(func[0]); i++) {
assert(!func[i]());
}
The best solution is likely to write a few extra lines of code when you add new test cases - it really isn't a big issue. I would recommend something along the lines of the function pointer array, as suggested in another answer.
However, just to show that everything is possible in C if you throw ugly macros at the problem, here is a not recommended alternative:
#include <assert.h>
#include <stdbool.h>
#include <stdio.h>
#define TEST_CASES \ // list of "x macros"
X(testcase1) \
X(testcase2) \
X(testcase3)
#define X(func) bool func (void); // declare function prototypes
TEST_CASES
#undef X
bool (*const test_cases[])(void) = // array of read-only function pointers
{
#define X(func) &func, // point at each function
TEST_CASES
#undef X
};
int main (void)
{
for(size_t i=0; i<sizeof(test_cases)/sizeof(test_cases[0]); i++)
{
assert(test_cases[i]());
}
}
bool testcase1 (void) { puts(__func__); return true; }
bool testcase2 (void) { puts(__func__); return true; }
bool testcase3 (void) { puts(__func__); return false; }
Output:
testcase1
testcase2
testcase3
Assertion failed!
For each new test case, you would only have to write a function definition and then add it to the "x macro" list TEST_CASES. However, you need very good reasons to introduce ugly tricks like these in production code!
You can use function pointers. Read also about closures (but C99 or C11 don't have them) and callbacks.
Many operating systems provide dynamic loading. On POSIX operating systems (such as Linux or MacOSX) you can get a function pointer (actually an address) from its name in some library (or in the program executable) using dlopen & dlsym. Other operating systems may provide similar functionalities.
At last, you should consider having your testing main function be generated by some script (or some program emitting C code), using metaprogramming techniques. So you would write something which generates the C code of your testing main having a long sequence of assert, and improve your build procedure (e.g. your Makefile if using make) to run appropriately that specialized C code generator. Details are of course specific to your code. You might add some conventions (e.g. add some special comment to be parsed by your test generator, etc...).
I decided to follow #Nominal Animal and #Basile Starynkevitch's approach. In mymainprog.c, I added -
int runtests(void){
void *testh;
int (*testp)(void);
char *dlmsg;
int rc;
char funcname[8];
int testnum;
testh = dlopen("libsmtests.so", RTLD_LAZY);
if (!testh){
printf("%s\n", dlerror());
return 1;
}
dlerror();
for (testnum =1; testnum < 1000; testnum++){
sprintf(funcname,"testcase%d", testnum);
*(void **) (&testp) = dlsym(testh, funcname);
dlmsg = dlerror();
if (dlmsg == NULL) {
rc = (*testp)();
printf("%s called, rc=%d\n", funcname, rc);
}
}
dlclose(testh);
return 0;
}
I add my testcases to a separate file (testcases.c) like this -
int testcase1(void){
return [some testcase expression]
}
int testcase2(void){
return [another testcase expression]
}
and then compile it as a shared library with position-independant code (-fPIC) to libsmtests.so. The advantage is slightly less typing since I don't need to code a call to testNNNN() after adding the implementation of a new functionint testcaseNNN(void) to testcases.c
I'm experimenting with memory management and trying to create something that will help with it in any way. Right now I'm trying to think is there any way to repeat the 'defer' functionality from Go in C.
Fast example for those who don't know what defer is:
package main
import "fmt"
func main() {
defer fmt.Println("1")
defer fmt.Println("2")
defer fmt.Println("3")
return
}
will print
3
2
1
So I'm thinking about some macros that will push the function with params to some stack and will call them when the function exit is called. Something like this:
int func(void)
{
MEMSTACK_INIT;
char * string = NULL;
node_t * node = NULL;
MEMSTACK_PUSH(free(string));
MEMSTACK_PUSH(NodeFree(&node));
<..>
switch (something)
{
case ONE : RETURN ERROR_ONE;
case TWO : RETURN ERROR_TWO;
case THR :
switch (something else)
{
<.. Many more code ..>
}
}
RETURN ERROR_GOOD;
}
Is there a way (except for making my own preprocessor, of course), to store somewhere a function call with params? In other words I want the previous code to be preprocessed in something like this:
int func(void)
{
<.. Some MEMSTACK initialisation stuff (if needed) ..>
char * string = NULL;
node_t * node = NULL;
<..>
switch (something)
{
case ONE :
free(string);
NodeFree(&node);
return ERROR_ONE;
case TWO :
free(string);
NodeFree(&node);
return ERROR_TWO;
case THR :
switch (something else)
{
<.. Many more code ..>
}
}
free(string);
NodeFree(&node);
return ERROR_GOOD;
}
It would be good thing for functions who require a lot of cleanup before exit.
Yes, yes, I know about goto cleanup trick.
I'm experimenting with memory management and trying to create something that will help with it in any way.
A good approach is to have only one return in any function. Possibly marked with a label (yes, so can gotoit, but this is also often discouraged). And of course: Be always sure to know who owns allocated memory and when (and where) ownership is transferred!
Now, let's...
[..] repeat the 'defer' functionality from Go in C.
First, in order to defer the call, we need to store the function (a pointer to it) as well as the evaluated arguments. Since C is statically typed, we need to unify that in a single type:
struct Fn {
void * parameters; // pointer to memory where the parameters are stored
void (*function)(void *); // pointer to function able to unpack parameters from above
struct Fn * next; // we want a stack, so ...
};
For each function that we are going to eventually defer, we need a way to store it's parameters. So we define a struct capable of holding the parameters and a function that is able to unpack the parameters from that struct:
#define MAKE_DEFERRABLE(name, N, ...) \
struct deferred_ ## name ## _parameters { PARAMS(N, __VA_ARGS__) }; \
void deferred_ ## name (void * p) { \
struct deferred_ ## name ## _parameters * parameters = p; \
printf(" -- Calling deferred " #name "\n"); \
(void)name(CPARAMS(N)); \
}
The N is the number of arguments. There are tricks to infer that from the __VA_ARGS__, but I'll leave that as an exercise for the reader. That macro contains two other macro expansions, PARAMS and CPARAMS. The former expands into a list suitable to define the struct contents. The later expands into code to extract the struct members as arguments:
#define PARAM_0(...)
#define PARAM_1(type, ...) type p1; PARAM_0(__VA_ARGS__)
#define PARAM_2(type, ...) type p2; PARAM_1(__VA_ARGS__)
#define PARAM_3(type, ...) type p3; PARAM_2(__VA_ARGS__)
#define PARAM_4(type, ...) type p4; PARAM_3(__VA_ARGS__)
#define PARAMS(N, ...) SPLICE(PARAM_, N)(__VA_ARGS__)
#define CPARAM_0
#define CPARAM_1 parameters->p1
#define CPARAM_2 parameters->p2, CPARAM_1
#define CPARAM_3 parameters->p3, CPARAM_2
#define CPARAM_4 parameters->p4, CPARAM_3
#define CPARAMS(N) SPLICE(CPARAM_, N)
If we'd want to defer functions with more than 4 parameters then this would need to be adjusted. The SPLICE is a nice little helper:
#define SPLICE_2(l,r) l##r
#define SPLICE_1(l,r) SPLICE_2(l,r)
#define SPLICE(l,r) SPLICE_1(l,r)
Next, we need to store the deferred functions somehow. For simplicity I choose to allocate them dynamically and keep a global pointer to the most recent:
struct Fn * deferred_fns = NULL;
Obviously you can extend this in many directions: Using (bounded) static storage, making it thread local, using per function deferred_fns, using alloca, ...
... but here's the simple, not production-ready (MISSING ERROR CHECKS) variant:
#define DEFER(name, N, ...) \
do { \
printf(" -- Deferring a call to " #name "\n"); \
if (deferred_fns == NULL) { \
deferred_fns = malloc(sizeof(*deferred_fns)); \
deferred_fns->next = NULL; \
} else { \
struct Fn * f = malloc(sizeof(*f)); \
f->next = deferred_fns; \
deferred_fns = f; \
} \
deferred_fns->function = &(deferred_ ## name); \
struct deferred_ ## name ##_parameters * parameters = malloc(sizeof(*parameters)); \
SPARAMS(N,__VA_ARGS__); \
deferred_fns->parameters = parameters; \
} while(0)
This just allocates a new struct Fn, makes it the top of the stack (read singly-linked list deferred_fns) and sets its members accordingly. The important SPARAMS saves the parameters into the corresponding struct:
#define SPARAM_0(...)
#define SPARAM_1(value, ...) parameters->p1 = (value); SPARAM_0(__VA_ARGS__)
#define SPARAM_2(value, ...) parameters->p2 = (value); SPARAM_1(__VA_ARGS__)
#define SPARAM_3(value, ...) parameters->p3 = (value); SPARAM_2(__VA_ARGS__)
#define SPARAM_4(value, ...) parameters->p4 = (value); SPARAM_3(__VA_ARGS__)
#define SPARAMS(N, ...) SPLICE(SPARAM_, N)(__VA_ARGS__)
Note: This fixes the order of parameter evaluation by making them evaluate from last to first. C does not mandate an evaluation order.
Finally, all that's left is a convenient way to run these deferred functions:
void run_deferred_fns(void) {
while (deferred_fns != NULL) {
deferred_fns->function(deferred_fns->parameters);
free(deferred_fns->parameters);
struct Fn * bye = deferred_fns;
deferred_fns = deferred_fns->next;
free(bye);
}
}
A small test:
void foo(int x) {
printf("foo: %d\n", x);
}
void bar(void) {
puts("bar");
}
void baz(int x, double y) {
printf("baz: %d %f\n", x, y);
}
MAKE_DEFERRABLE(foo, 1, int);
MAKE_DEFERRABLE(bar, 0);
MAKE_DEFERRABLE(baz, 2, int, double);
int main(void) {
DEFER(foo, 1, 42);
DEFER(bar, 0);
DEFER(foo, 1, 21);
DEFER(baz, 2, 42, 3.14);
run_deferred_fns();
return 0;
}
In order to achieve the same behavior as in your example, make deferred_fns a local variable, and pass that as parameter to run_deferred_fns. Wrap in simple macros, done:
#define PREPARE_DEFERRED_FNS struct Fn * deferred_fns = NULL;
#define RETURN(x) do { run_deferred_fns(deferred_fns); return (x); } while (0)
Welcome to insanity.
Note: My solution works at the "source level". By that I mean that you need to specify defer-able functions in the source code. That implies that you cannot, for example, defer a function loaded through dlopen. There's also a different approach, working at the ABI level, if you will: avcall, part of libffcall.
Now, I need really need my parentheses ... lots of them (())))(()(((()