I want to use nftw to traverse a directory structure in C.
However, given what I want to do, I don't see a way around using a global variable.
The textbook examples of using (n)ftw all involve doing something like printing out a filename. I want, instead, to take the pathname and file checksum and place those in a data structure. But I don't see a good way to do that, given the limits on what can be passed to nftw.
The solution I'm using involves a global variable. The function called by nftw can then access that variable and add the required data.
Is there any reasonable way to do this without using a global variable?
Here's the exchange in previous post on stackoverflow in which someone suggested I post this as a follow-up.
Using ftw can be really, really bad. Internally it will save the the function pointer that you use, if another thread then does something else it will overwrite the function pointer.
Horror scenario:
thread 1: count billions of files
thread 2: delete some files
thread 1: ---oops, it is now deleting billions of
files instead of counting them.
In short. You are better off using fts_open.
If you still want to use nftw then my suggestion is to put the "global" type in a namespace and mark it as "thread_local". You should be able to adjust this to your needs.
/* in some cpp file */
namespace {
thread_local size_t gTotalBytes{0}; // thread local makes this thread safe
int GetSize(const char* path, const struct stat* statPtr, int currentFlag, struct FTW* internalFtwUsage) {
gTotalBytes+= statPtr->st_size;
return 0; //ntfw continues
}
} // namespace
size_t RecursiveFolderDiskUsed(const std::string& startPath) {
const int flags = FTW_DEPTH | FTW_MOUNT | FTW_PHYS;
const int maxFileDescriptorsToUse = 1024; // or whatever
const int result = nftw(startPath.c_str(), GetSize, maxFileDescriptorsToUse , flags);
// log or something if result== -1
return gTotalBytes;
}
No. nftw doesn't offer any user parameter that could be passed to the function, so you have to use global (or static) variables in C.
GCC offers an extension "nested function" which should capture the variables of their enclosing scopes, so they could be used like this:
void f()
{
int i = 0;
int fn(const char *,
const struct stat *, int, struct FTW *) {
i++;
return 0;
};
nftw("path", fn, 10, 0);
}
The data is best given static linkage (i.e. file-scope) in a separate module that includes only functions required to access the data, including the function passed to nftw(). That way the data is not visible globally and all access is controlled. It may be that the function that calls ntfw() is also part of this module, enabling the function passed to nftw() to also be static, and thus invisible externally.
In other words, you should do what you are probably doing already, but use separate compilation and static linkage judiciously to make the data only visible via access functions. Data with static linkage is accessible by any function within the same translation unit, and you avoid the problems associated with global variables by only including functions in that translation unit that are creators, maintainers or accessors of that data.
The general pattern is:
datamodule.h
#if defined DATAMODULE_INCLUDE
<type> create_data( <args>) ;
<type> get_data( <args> ) ;
#endif
datamodule.c
#include "datamodule.h"
static <type> my_data ;
static int nftwfunc(const char *filename, const struct stat *statptr, int fileflags, struct FTW *pfwt)
{
// update/add to my_data
...
}
<type> create_data( const char* path, <other args>)
{
...
ret = nftw( path, nftwfunc, fd_limit, flags);
...
}
<type> get_data( <args> )
{
// Get requested data from my_data and return it to caller
}
Related
Is this way of defining a "global variable" valid / a good approach?
While I would like this variable to be used whenever the header file is included to store program states.
/* global.h */
...
typedef struct {
int some_count;
....
} ProgramState;
ProgramState *GetProgramState()
...
/* global.c */
...
#include "global.h"
ProgramState *GetProgramState()
{
static ProgramState *prog_state = NULL;
if (!prog_state) {
prog_state = (ProgramState *) malloc(sizeof(ProgamState));
*prog_state = (ProgamState) {
.some_count = 1
};
}
return prog_state;
}
...
/* main.c */
#include "global.h"
int main(void)
{
GetProgramState()->some_count++;
printf("%d\n", GetProgramState()->some_count);
return 0;
}
While I know this way induced some overheads (while calling the method?), and there are ways like extern (using the extern way requires a specific initialize function).
Please let me know if there are other alternatives, thanks!
This is effectively an accessor. An accessor gives control over how a variable is accessed, allowing checks (e.g. validation) to be performed, and allowing the specific implementation of the variable to be changed. Using accessors is a common and perfectly acceptable programming paradigm.
As you mentioned, the alternative would be to access the variable directly. And while you could initialize it (contrary to what you said), it can only be initialized using a constant expression (e.g. NULL, but not malloc(sizeof(ProgamState))).
I am currently writing a small game in C and feel like I can't get away from global variables.
For example I am storing the player position as a global variable because it's needed in other files. I have set myself some rules to keep the code clean.
Only use a global variable in the file it's defined in, if possible
Never directly change the value of a global from another file (reading from another file using extern is okay)
So for example graphics settings would be stored as file scope variables in graphics.c. If code in other files wants to change the graphics settings they would have to do so through a function in graphics.c like graphics_setFOV(float fov).
Do you think those rules are sufficient for avoiding global variable hell in the long term?
How bad are file scope variables?
Is it okay to read variables from other files using extern?
Typically, this kind of problem is handled by passing around a shared context:
graphics_api.h
#ifndef GRAPHICS_API
#define GRAPHICS_API
typedef void *HANDLE;
HANDLE init_graphics(void);
void destroy_graphics(HANDLE handle);
void use_graphics(HANDLE handle);
#endif
graphics.c
#include <stdio.h>
#include <stdlib.h>
#include "graphics_api.h"
typedef struct {
int width;
int height;
} CONTEXT;
HANDLE init_graphics(void) {
CONTEXT *result = malloc(sizeof(CONTEXT));
if (result) {
result->width = 640;
result->height = 480;
}
return (HANDLE) result;
}
void destroy_graphics(HANDLE handle) {
CONTEXT *context = (CONTEXT *) handle;
if (context) {
free(context);
}
}
void use_graphics(HANDLE handle) {
CONTEXT *context = (CONTEXT *) handle;
if (context) {
printf("width = %5d\n", context->width);
printf("height = %5d\n", context->height);
}
}
main.c
#include <stdio.h>
#include "graphics_api.h"
int main(void) {
HANDLE handle = init_graphics();
if (handle) {
use_graphics(handle);
destroy_graphics(handle);
}
return 0;
}
Output
width = 640
height = 480
Hiding the details of the context by using a void pointer prevents the user from changing the data contained within the memory to which it points.
How do you avoid using global variables in inherently stateful programs?
By passing arguments...
// state.h
/// state object:
struct state {
int some_value;
};
/// Initializes state
/// #return zero on success
int state_init(struct state *s);
/// Destroys state
/// #return zero on success
int state_fini(struct state *s);
/// Does some operation with state
/// #return zero on success
int state_set_value(struct state *s, int new_value);
/// Retrieves some operation from state
/// #return zero on success
int state_get_value(struct state *s, int *value);
// state.c
#include "state.h"
int state_init(struct state *s) {
s->some_value = -1;
return 0;
}
int state_fini(struct state *s) {
// add free() etc. if needed here
// call fini of other objects here
return 0;
}
int state_set_value(struct state *s, int value) {
if (value < 0) {
return -1; // ERROR - invalid argument
// you may return EINVAL here
}
s->some_value = value;
return 0; // success
}
int state_get_value(struct state *s, int *value) {
if (s->some_value < 0) { // value not set yet
return -1;
}
*value = s->some_value;
return 0;
}
// main.c
#include "state.h"
#include <stdlib.h>
#include <stdio.h>
int main() {
struct state state; // local variable
int err = state_init(&state);
if (err) abort();
int value;
err = state_get_value(&state, &value);
if (err != 0) {
printf("Getting value errored: %d\n", err);
}
err = state_set_value(&state, 50);
if (err) abort();
err = state_get_value(&state, &value);
if (err) abort();
printf("Current value is: %d\n", value);
err = state_fini(&state);
if (err) abort();
}
The only single case where global variables (preferably only a single pointer to some stack variable anyway) have to be used are signal handlers. The standard way would be to only increment a single global variable of type sig_atomic_t inside a signal handler and do nothing else - then execute all signal handling related logic from the normal flow in the rest of the code by checking the value of that variable. (On POSIX system) all other asynchronous communication from the kernel, like timer_create, that take sigevent structure, they can pass arguments to notified function by using members in union sigval.
Do you think those rules are sufficient for avoiding global variable hell in the long term?
Subjectively: no. I believe that a potentially uneducated programmer has too much freedom in creating global variables given the first rule. In complex programs I would use a hard rule: Do not use global variables. If finally after researching all other ways and all other possibilities have been exhausted and you have to use a global variables, make sure global variables leave the smallest possible memory footprint.
In simple short programs I wouldn't care much.
How bad are file scope variables?
This is opinion based - there are good cases where projects use many global variables. I believe that topic is exhausted in are global variables bad and numerous other internet resources.
Is it okay to read variables from other files using extern?
Yes, it's ok.
There are no "hard rules" and each project has it's own rules. I also recommend to read c2 wiki global variables are bad.
The first thing you have to ask yourself is: Just why did the programming world come to loath global variables? Obviously, as you noted, the way to model a global state is essentially a global (set of) variable(s). So what's the problem with that?
The Problem
All parts of the program have access to that state. The whole program becomes tightly coupled. Global variables violate the prime directive in programming, divide and conquer. Once all functions operate on the same data you can as well do away with the functions: They are no longer logical separations of concern but degrade to a notational convenience to avoid large files.
Write access is worse than read access: You'll have a hard time finding out just why on earth the state is unexpected at a certain point; the change can have happened anywhere. It is tempting to take shortcuts: "Ah, we can make the state change right here instead of passing a computation result back up three layers to the caller; that makes the code much smaller."
Even read access can be used to cheat and e.g. change behavior of some deep-down code depending on some global information: "Ah, we can skip rendering, there is no display yet!" A decision which should not be made in the rendering code but at top level. What if top level renders to a file!?
This creates both a debugging and a development/maintenance nightmare. If every piece of the code potentially relies on the presence and semantics of certain variables — and can change them! — it becomes exponentially harder to debug or change the program. The code agglomerating around the global data is like a cast, or perhaps a Boa Constrictor, which starts to immobilize and strangle your program.
Such programming can be avoided with (self-)discipline, but imagine a large project with many teams! It's much better to "physically" prevent access. Not coincidentally all programming languages after C, even if they are otherwise fundamentally different, come with improved modularization.
So what can we do?
The solution is indeed to pass parameters to functions, as KamilCuk said; but each function should only get the information they legitimately need. Of course it is best if the access is read-only and the result is a return value: Pure functions cannot change state at all and thus perfectly separate concerns.
But simply passing a pointer to the global state around does not cut the mustard: That's only a thinly veiled global variable.
Instead, the state should be separated into sub-states. Only top-level functions (which typically do not do much themselves but mostly delegate) have access to the overall state and hand sub-states to the functions they call. Third-tier functions get sub-sub states, etc. The corresponding implementation in C is a nested struct; pointers to the members — const whenever possible — are passed to functions which therefore cannot see, let alone alter, the rest of the global state. Separation of concerns is thus guaranteed.
I am writing a large C program for embedded use. Every module in this program has an init() function (like a constructor) to set up its static variables.
The problem is that I have to remember to call all of these init functions from main(). I also have to remember to put them back if I have commented them out for some reason.
Is there anything clever I do to make sure that all of these functions are getting called? Something along the lines of putting a macro in each init function that, when you call a check_inited() function later, sends a warning to STDOUT if not all the functions are called.
I could increment a counter, but I'd have to maintain the correct number of init functions somewhere and that is also prone to error.
Thoughts?
The following is the solution I decided on, with input from several people in this thread
My goal is to make sure that all my init functions are actually being called. I want to do
this without maintaining lists or counts of modules across several files. I can't call
them automatically as Nick D suggested because they need to be called in a certain order.
To accomplish this, a macro included in every module uses the gcc constructor attribute to
add the init function name to a global list.
Another macro included in the body of the init function updates the global list to make a
note that the function was actually called.
Finally, a check function is called in main() after all of the inits are done.
Notes:
I chose to copy the strings into an array. This not strictly necessary because the
function names passed will always be static strings in normal usage. If memory was short
you could just store a pointer to the string that was passed in.
My reusable library of utility functions is called "nx_lib". Thus all the 'nxl' designations.
This isn't the most efficient code in the world but it's only called a boot time so that
doesn't matter for me.
There are two lines of code that need to be added to each module. If either is omitted,
the check function will let you know.
you might be able to make the constructor function static, which would avoid the need to give it a name that is unique across the project.
this code is only lightly tested and it's really late so please check carefully before trusting it.
Thank you to:
pierr who introduced me to the constructor attribute.
Nick D for demonstrating the ## preprocessor trick and giving me the framework.
tod frye for a clever linker-based approach that will work with many compilers.
Everyone else for helping out and sharing useful tidbits.
nx_lib_public.h
This is the relevant fragment of my library header file
#define NX_FUNC_RUN_CHECK_NAME_SIZE 20
typedef struct _nxl_function_element{
char func[NX_FUNC_RUN_CHECK_NAME_SIZE];
BOOL called;
} nxl_function_element;
void nxl_func_run_check_add(char *func_name);
BOOL nxl_func_run_check(void);
void nxl_func_run_check_hit(char *func_name);
#define NXL_FUNC_RUN_CHECK_ADD(function_name) \
void cons_ ## function_name() __attribute__((constructor)); \
void cons_ ## function_name() { nxl_func_run_check_add(#function_name); }
nxl_func_run_check.c
This is the libary code that is called to add function names and check them later.
#define MAX_CHECKED_FUNCTIONS 100
static nxl_function_element m_functions[MAX_CHECKED_FUNCTIONS];
static int m_func_cnt = 0;
// call automatically before main runs to register a function name.
void nxl_func_run_check_add(char *func_name)
{
// fail and complain if no more room.
if (m_func_cnt >= MAX_CHECKED_FUNCTIONS) {
print ("nxl_func_run_check_add failed, out of space\r\n");
return;
}
strncpy (m_functions[m_func_cnt].func, func_name,
NX_FUNC_RUN_CHECK_NAME_SIZE);
m_functions[m_func_cnt].func[NX_FUNC_RUN_CHECK_NAME_SIZE-1] = 0;
m_functions[m_func_cnt++].called = FALSE;
}
// call from inside the init function
void nxl_func_run_check_hit(char *func_name)
{
int i;
for (i=0; i< m_func_cnt; i++) {
if (! strncmp(m_functions[i].func, func_name,
NX_FUNC_RUN_CHECK_NAME_SIZE)) {
m_functions[i].called = TRUE;
return;
}
}
print("nxl_func_run_check_hit(): error, unregistered function was hit\r\n");
}
// checks that all registered functions were called
BOOL nxl_func_run_check(void) {
int i;
BOOL success=TRUE;
for (i=0; i< m_func_cnt; i++) {
if (m_functions[i].called == FALSE) {
success = FALSE;
xil_printf("nxl_func_run_check error: %s() not called\r\n",
m_functions[i].func);
}
}
return success;
}
solo.c
This is an example of a module that needs initialization
#include "nx_lib_public.h"
NXL_FUNC_RUN_CHECK_ADD(solo_init)
void solo_init(void)
{
nxl_func_run_check_hit((char *) __func__);
/* do module initialization here */
}
You can use gcc's extension __attribute__((constructor)) if gcc is ok for your project.
#include <stdio.h>
void func1() __attribute__((constructor));
void func2() __attribute__((constructor));
void func1()
{
printf("%s\n",__func__);
}
void func2()
{
printf("%s\n",__func__);
}
int main()
{
printf("main\n");
return 0;
}
//the output
func2
func1
main
I don't know how ugly the following looks but I post it anyway :-)
(The basic idea is to register function pointers, like what atexit function does.
Of course atexit implementation is different)
In the main module we can have something like this:
typedef int (*function_t)(void);
static function_t vfunctions[100]; // we can store max 100 function pointers
static int vcnt = 0; // count the registered function pointers
int add2init(function_t f)
{
// todo: error checks
vfunctions[vcnt++] = f;
return 0;
}
...
int main(void) {
...
// iterate vfunctions[] and call the functions
...
}
... and in some other module:
typedef int (*function_t)(void);
extern int add2init(function_t f);
#define M_add2init(function_name) static int int_ ## function_name = add2init(function_name)
int foo(void)
{
printf("foo\n");
return 0;
}
M_add2init(foo); // <--- register foo function
Why not write a post processing script to do the checking for you. Then run that script as part of your build process... Or better yet, make it one of your tests. You are writing tests, right? :)
For example, if each of your modules has a header file, modX.c. And if the signature of your init() function is "void init()"...
Have your script grep through all your .h files, and create a list of module names that need to be init()ed. Then have the script check that init() is indeed called on each module in main().
If your single module represents "class" entity and has instance constructor, you can use following construction:
static inline void init(void) { ... }
static int initialized = 0;
#define INIT if (__predict_false(!initialized)) { init(); initialized = 1; }
struct Foo *
foo_create(void)
{
INIT;
...
}
where "__predict_false" is your compiler's branch prediction hint. When first object is created, module is auto-initialized (for once).
Splint (and probably other Lint variants) can give a warning about functions that are defined but not called.
It's interesting that most compilers will warn you about unused variables, but not unused functions.
Larger running time is not a problem
You can conceivably implement a kind of "state-machine" for each module, wherein the actions of a function depend on the state the module is in. This state can be set to BEFORE_INIT or INITIALIZED.
For example, let's say we have module A with functions foo and bar.
The actual logic of the functions (i.e., what they actually do) would be declared like so:
void foo_logic();
void bar_logic();
Or whatever the signature is.
Then, the actual functions of the module (i.e., the actual function declared foo()) will perform a run-time check of the condition of the module, and decide what to do:
void foo() {
if (module_state == BEFORE_INIT) {
handle_not_initialized_error();
}
foo_logic();
}
This logic is repeated for all functions.
A few things to note:
This will obviously incur a huge penalty performance-wise, so is
probably not a good idea (I posted
anyway because you said runtime is
not a problem).
This is not a real state-machine, since there are only two states which are checked using a basic if, without some kind of smart general logic.
This kind of "design-pattern" works great when you're using separate threads/tasks, and the functions you're calling are actually called using some kind of IPC.
A state machine can be nicely implemented in C++, might be worth reading up on it. The same kind of idea can conceivably be coded in C with arrays of function pointers, but it's almost certainly not worth your time.
you can do something along these lines with a linker section. whenever you define an init function, place a pointer to it in a linker section just for init function pointers. then you can at least find out how many init functions have been compiled.
and if it does not matter what order the init functions are called, and the all have the same prototype, you can just call them all in a loop from main.
the exact details elude my memory, but it works soemthing like this::
in the module file...
//this is the syntax in GCC..(or would be if the underscores came through in this text editor)
initFuncPtr thisInit __attribute((section(.myinits)))__= &moduleInit;
void moduleInit(void)
{
// so init here
}
this places a pointer to the module init function in the .myinits section, but leaves the code in the .code section. so the .myinits section is nothing but pointers. you can think of this as a variable length array that module files can add to.
then you can access the section start and end address from the main. and go from there.
if the init functions all have the same protoytpe, you can just iterate over this section, calling them all.
this, in effect, is creating your own static constructor system in C.
if you are doing a large project and your linker is not at least this fully featured, you may have a problem...
Can I put up an answer to my question?
My idea was to have each function add it's name to a global list of functions, like Nick D's solution.
Then I would run through the symbol table produced by -gstab, and look for any functions named init_* that had not been called.
This is an embedded app so I have the elf image handy in flash memory.
However I don't like this idea because it means I always have to include debugging info in the binary.
I am working on an embedded application where the device is controlled through a command interface. I mocked the command dispatcher in VC and had it working to my satisfaction; but when I then moved the code over to the embedded environment, I found out that the compiler has a broken implementation of pointer-to-func's.
Here's how I originally implemented the code (in VC):
/* Relevant parts of header file */
typedef struct command {
const char *code;
void *set_dispatcher;
void *get_dispatcher;
const char *_description;
} command_t;
#define COMMAND_ENTRY(label,dispatcher,description) {(const char*)label, &set_##dispatcher, &get_##dispatcher, (const char*)description}
/* Dispatcher data structure in the C file */
const command_t commands[] = {
COMMAND_ENTRY("DH", Dhcp, "DHCP (0=off, 1=on)"),
COMMAND_ENTRY("IP", Ip, "IP Address (192.168.1.205)"),
COMMAND_ENTRY("SM", Subnet, "Subunet Mask (255.255.255.0)"),
COMMAND_ENTRY("DR", DefaultRoute, "Default router (192.168.1.1)"),
COMMAND_ENTRY("UN", Username, "Web username"),
COMMAND_ENTRY("PW", Password, "Web password"),
...
}
/* After matching the received command string to the command "label", the command is dispatched */
if (pc->isGetter)
return ((get_fn_t)(commands[i].get_dispatcher))(pc);
else
return ((set_fn_t)(commands[i].set_dispatcher))(pc);
}
Without the use of function pointers, it seems like my only hope is to use switch()/case statements to call functions. But I'd like to avoid having to manually maintain a large switch() statement.
What I was thinking of doing is moving all the COMMAND_ENTRY lines into a separate include file. Then wraps that include file with varying #define and #undefines. Something like:
/* Create enum's labels */
#define COMMAND_ENTRY(label,dispatcher,description) SET_##dispatcher, GET_##dispatcher
typedef enum command_labels = {
#include "entries.cinc"
DUMMY_ENUM_ENTRY} command_labels_t;
#undefine COMMAND_ENTRY
/* Create command mapping table */
#define COMMAND_ENTRY(label,dispatcher,description) {(const char*)label, SET_##dispatcher, GET_##dispatcher, (const char*)description}
const command_t commands[] = {
#include "entries.cinc"
NULL /* dummy */ };
#undefine COMMAND_ENTRY
/*...*/
int command_dispatcher(command_labels_t dispatcher_id) {
/* Create dispatcher switch statement */
#define COMMAND_ENTRY(label,dispatcher,description) case SET_##dispatcher: return set_##dispatcher(pc); case GET_##dispatcher: return get_##dispatcher(pc);
switch(dispatcher_id) {
#include "entries.cinc"
default:
return NOT_FOUND;
}
#undefine COMMAND_ENTRY
}
Does anyone see a better way to handle this situation? Sadly, 'get another compiler' is not a viable option. :(
--- Edit to add:
Just to clarify, the particular embedded environment is broken in that the compiler is supposed to create a "function-pointer table" which is then used by the compiler to resolve calls to functions through a pointer. Unfortunately, the compiler is broken and doesn't generate a correct function-table.
So I don't have an easy way to extract the func address to invoke it.
--- Edit #2:
Ah, yes, the use of void *(set|get)_dispatcher was my attempt to see if the problem was with the typedefine of the func pointers. Originally, I had
typedef int (*set_fn_t)(cmdContext_t *pCmdCtx);
typedef int (*get_fn_t)(cmdContext_t *pCmdCtx);
typedef struct command {
const char *code;
set_fn_t set_dispatcher;
get_fn_t get_dispatcher;
const char *_description;
} command_t;
You should try changing your struct command so the function pointers have the actual type:
typedef struct command {
const char *code;
set_fn_t set_dispatcher;
get_fn_t get_dispatcher;
const char *_description;
} command_t;
Unfortunately, function pointers are not guaranteed to be able to convert to/from void pointers (that applies only to pointers to objects).
What's the embedded environment?
Given the information posted in the updates to the question, I see that it's really a bugged compiler.
I think that your proposed solution seems pretty reasonable - it's probably similar to what I would have come up with.
A function pointer isn't actually required to fit in a void*. You could check to make sure that the value you're calling is actually the address of the function. If not, use a function pointer type in the struct: either get_fn_t, or IIRC void(*)(void) is guaranteed to be compatible with any function pointer type.
Edit: OK, assuming that calling by value can't be made to work, I can't think of a neater way to do what you need than auto-generating the switch statement. You could maybe use an off-the-shelf ASP-style preprocessor mode for ruby/python/perl/php/whatever prior to the C preprocessor. Something like this:
switch(dispatcher_id) {
<% for c in commands %>
case SET_<% c.dispatcher %>: return set_<% c.dispatcher %>(pc);
case GET_<% c.dispatcher %>: return get_<% c.dispatcher %>(pc);
<% end %>
default:
return NOT_FOUND;
}
might be a bit more readable than the macro/include trick, but introducing a new tool and setting up the makefiles is probably not worth it for such a small amount of code. And the line numbers in the debug info won't relate to the file you think of as the source file unless you do extra work in your preprocessor to specify them.
Can you get the vendor to fix the compiler?
To what extent is the pointer-to-function broken?
If the compiler allows you to get the address of a function (I'm from C++, but &getenv is what I mean), you could wrap the calling convention stuff into assembler.
As said, I'm a C++ssie, but something in the way of
; function call
push [arg1]
push [arg2]
call [command+8] ; at the 4th location, the setter is stored
ret
If even that is broken, you could define an array of extern void* pointers which you define, again, in assembly.
try this syntax:
return (*((get_fn_t)commands[i].get_dispatcher))(pc);
It's been awhile since I've done C & function pointers, but I believe the original C syntax required the * when dereferencing function pointers but most compilers would let you get away without it.
Do you have access to the link map?
If so, maybe you can hack your way around the wonky function-pointer table:
unsigned long addr_get_dhcp = 0x1111111;
unsigned long addr_set_dhcp = 0x2222222; //make these unique numbers.
/* Relevant parts of header file */
typedef struct command {
const char *code;
unsigned long set_dispatcher;
unsigned long get_dispatcher;
const char *_description;
} command_t;
#define COMMAND_ENTRY(label,dispatcher,description) {(const char*)label,
addr_set_##dispatcher, addr_get_##dispatcher, (const char*)description}
Now compile, grab the relevant addresses from the link map, replace the constants, and recompile. Nothing should move, so the map ought to stay the same. (Making the original constants unique should prevent the compiler from collapsing identical values into one storage location. You may need a long long, depending on the architecture)
If the concept works, you could probably add a post-link step running a script to do the replacement automagically. Of course, this is just a theory, it may fail miserably.
Maybe, you need to look into the structure again:
typedef struct command {
const char *code;
void *set_dispatcher; //IMO, it does not look like a function pointer...
void *get_dispatcher; //more like a pointer to void
const char *_description;
} command_t;
Let say your dispatchers have the following similar function definition:
//a function pointer type definition
typedef int (*genericDispatcher)(int data);
Assume that the dispatchers are like below:
int set_DhcpDispatcher(int data) { return data; }
int get_DhcpDispatcher(int data) { return 2*data; }
So, the revised structure will be:
typedef struct command {
const char *code;
genericDispatcher set_dispatcher;
genericDispatcher get_dispatcher;
const char *_description;
} command_t;
Your macro will be:
#define COMMAND_ENTRY(label,dispatcher,description) \
{ (const char*)label, \
set_##dispatcher##Dispatcher, \
get_##dispatcher##Dispatcher, \
(const char*)description }
Then, you can set your array as usual:
int main(int argc, char **argv)
{
int value1 = 0, value2 = 0;
const command_t commands[] = {
COMMAND_ENTRY("DH", Dhcp, "DHCP (0=off, 1=on)")
};
value1 = commands[0].set_dispatcher(1);
value2 = commands[0].get_dispatcher(2);
printf("value1 = %d, value2 = %d", value1, value2);
return 0;
}
Correct me, if I am wrong somewhere... ;)
What's the best way to create a singleton in C? A concurrent solution would be nice.
I am aware that C isn't the first language you would use for a singleton.
First, C is not suitable for OO programming. You'd be fighting all the way if you do. Secondly, singletons are just static variables with some encapsulation. So you can use a static global variable. However, global variables typically have far too many ills associated with them. You could otherwise use a function local static variable, like this:
int *SingletonInt() {
static int instance = 42;
return &instance;
}
or a smarter macro:
#define SINGLETON(t, inst, init) t* Singleton_##t() { \
static t inst = init; \
return &inst; \
}
#include <stdio.h>
/* actual definition */
SINGLETON(float, finst, 4.2);
int main() {
printf("%f\n", *(Singleton_float()));
return 0;
}
And finally, remember, that singletons are mostly abused. It is difficult to get them right, especially under multi-threaded environments...
You don't need to. C already has global variables, so you don't need a work-around to simulate them.
It's the same as the C++ version pretty much. Just have a function that returns an instance pointer. It can be a static variable inside the function. Wrap the function body with a critical section or pthread mutex, depending on platform.
#include <stdlib.h>
struct A
{
int a;
int b;
};
struct A* getObject()
{
static struct A *instance = NULL;
// do lock here
if(instance == NULL)
{
instance = malloc(sizeof(*instance));
instance->a = 1;
instance->b = 2;
}
// do unlock
return instance;
};
Note that you'd need a function to free up the singleton too. Especially if it grabs any system resources that aren't automatically released on process exit.
EDIT: My answer presumes the singleton you are creating is somewhat complex and has a multi-step creation process. If it's just static data, go with a global like others have suggested.
A singleton in C will be very weird . . . I've never seen an example of "object oriented C" that looked particularly elegant. If possible, consider using C++. C++ allows you to pick and choose which features you want to use, and many people just use it as a "better C".
Below is a pretty typical pattern for lock-free one-time initialization. The InterlockCompareExchangePtr atomically swaps in the new value if the previous is null. This protects if multiple threads try to create the singleton at the same time, only one will win. The others will delete their newly created object.
MyObj* g_singleton; // MyObj is some struct.
MyObj* GetMyObj()
{
MyObj* singleton;
if (g_singleton == NULL)
{
singleton = CreateNewObj();
// Only swap if the existing value is null. If not on Windows,
// use whatever compare and swap your platform provides.
if (InterlockCompareExchangePtr(&g_singleton, singleton, NULL) != NULL)
{
DeleteObj(singleton);
}
}
return g_singleton;
}
DoSomethingWithSingleton(GetMyObj());
Here's another perspective: every file in a C program is effectively a singleton class that is auto instantiated at runtime and cannot be subclassed.
Global static variables are your private class members.
Global non static are public (just declare them using extern in some header file).
Static functions are private methods
Non-static functions are the public ones.
Give everything a proper prefix and now you can use my_singleton_method() in lieu of my_singleton.method().
If your singleton is complex you can write a generate_singleton() method to initialize it before use, but then you need to make sure all the other public methods check if it was called and error out if not.
I think this solution might be the simplest and best for most use cases...
In this example, I am creating a single instance global dispatch queue, which you'd definitely do, say, if you were tracking dispatch source events from multiple objects; in that case, every object listening to the queue for events could be notified when a new task is added to the queue. Once the global queue is set (via queue_ref()), it can be referenced with the queue variable in any file in which the header file is included (examples are provided below).
In one of my implementations, I called queue_ref() in AppDelegate.m (main.c would work, too). That way, queue will be initialized before any other calling object attempts to access it. In the remaining objects, I simply called queue. Returning a value from a variable is much faster than calling a function, and then checking the value of the variable before returning it.
In GlobalQueue.h:
#ifndef GlobalQueue_h
#define GlobalQueue_h
#include <stdio.h>
#include <dispatch/dispatch.h>
extern dispatch_queue_t queue;
extern dispatch_queue_t queue_ref(void);
#endif /* GlobalQueue_h */
In GlobalQueue.c:
#include "GlobalQueue.h"
dispatch_queue_t queue;
dispatch_queue_t queue_ref(void) {
if (!queue) {
queue = dispatch_queue_create_with_target("GlobalDispatchQueue", DISPATCH_QUEUE_SERIAL, dispatch_get_main_queue());
}
return queue;
}
To use:
#include "GlobalQueue.h" in any Objective-C or C implementation source file.
Call queue_ref() to use the dispatch queue. Once queue_ref() has been called, the queue can be used via the queue variable in all source files
Examples:
Calling queue_ref():
dispatch_queue_t serial_queue_with_queue_target = dispatch_queue_create_with_target("serial_queue_with_queue_target", DISPATCH_QUEUE_SERIAL, **queue_ref()**);
Calling queue:
dispatch_queue_t serial_queue_with_queue_target = dispatch_queue_create_with_target("serial_queue_with_queue_target", DISPATCH_QUEUE_SERIAL, **queue**));]
Just do
void * getSingleTon() {
static Class object = (Class *)malloc( sizeof( Class ) );
return &object;
}
which works in a concurrent environment too.