I am having a list of parameters. Each parameter is defined by an unique identifier (ParamID) and some other data (&ParamX, SomeOtherDataX) associated with this parameter. All the available parameters are organized in a table, which is implemented as a struct array (ParameterList[]) in C. Thus, on each row I can see all associated data for one parameter. The following code snippet should (hopefully) make this clearer:
// predefined IDs; not changeable!
#define PARAM_ID_A 10
#define PARAM_ID_B 12
#define PARAM_ID_C 14
// the basic structure of my parameter list
typedef struct ParameterList_t {
int ParamID,
*int ParamAddr,
*float SomeConnectedData
}
// definition of my list in ROM
const ParameterList_t ParameterList[] = {
{ PARAM_ID_A, &Param1, SomeOtherData1},
{ PARAM_ID_B, &Param2, SomeOtherData2},
{ PARAM_ID_C, &Param3, SomeOtherData3}
};
Now I want to create another list, which contains references on a subset of the parameters defined in the ParameterList[] table. This list should also be resided in ROM. I basically want to access all associated data for a subset of the parameters.
const *ParameterList_t ParameterSubListA[] = {
&ParameterList[2], // parameter: PARAM_ID_B
&ParameterList[3], // parameter: PARAM_ID_C
};
The problem here is that the code will be maintained by many people and the parameter list (ParameterList[]) might change frequently and parameters will be sorted into the table at the beginning or in the middle. This means the sub list (ParameterSubListA[]) must be updated to point to the desired parameters if their index (index = row in ParameterList[]) changes.
Question:
Basically my code needs a mapping from ParamID to the index of the ParameterList[] table, preferably by use of the preprocessor and only in ROM. I found different ways to implement this, which are all not satisfying:
Option 1:
Automatically generate a list in the RAM at startup, which maps the ParamID to the index in ParameterList[]. What I get is an array, that could be called CrossRefTable[]:
IndexOfParameterA_InParameterList = CrossRefTable[PARAM_ID_A];
My sublist would then look like this (cannot be constant anymore :/ ):
*ParameterList_t ParameterSubListA[] = {
&ParameterList[CrossRefTable[PARAM_ID_B]], // parameter: PARAM_ID_B
&ParameterList[CrossRefTable[PARAM_ID_C]], // parameter: PARAM_ID_C
};
I am short of RAM, so I would prefer a solution that only uses ROM.
Option 2:
Use a predefined macro __COUNTER__, which increments with each call and generate a macro in each row:
const ParameterList_t ParameterList[] = {
{ PARAM_ID_A, &Param1, SomeOtherData1},
#define PARAM_IDX_A __COUNTER__
{ PARAM_ID_B, &Param2, SomeOtherData2},
#define PARAM_IDX_B __COUNTER__
{ PARAM_ID_C, &Param3, SomeOtherData3}
#define PARAM_IDX_C __COUNTER__
};
My sublist would then look like this:
const *ParameterList_t ParameterSubListA[] = {
&ParameterList[PARAM_IDX_B], // parameter: PARAM_ID_B
&ParameterList[PARAM_IDX_C], // parameter: PARAM_ID_C
};
I would favorise this option, apparently it is not possible to use GCC.
Other Options:
I also figured there might be a possiblity in using X-MACROS, but I am not sure about that.
Boost is also not an option.
Hopefully my explanation is somehow clear...
Since the data is static, I'd say go on and initialize it statically.
Using external tools if the compiler is not capable enough.
parameter_list.c:
const struct ParameterList_t ParameterList[] = {
{ PARAM_ID_A, &Param1, SomeOtherData1},
{ PARAM_ID_C, &Param2, SomeOtherData2},
{ PARAM_ID_B, &Param3, SomeOtherData3}
};
#include "parameter_list_index.h"
const *ParameterList_t ParameterSubListA[] = {
&ParameterList[PARAM_ID_C_INDEX],
&ParameterList[PARAM_ID_B_INDEX],
};
parameter_list.px:
#!/usr/bin/perl -n
print "#define $1_INDEX ".($n++)."\n" if
/^const.*ParameterList\[\]/../^}/ and /^\s*{\s*([^,]+)/;
Makefile:
parameter_list.o: parameter_list.c parameter_list.h
parameter_list_index.h: parameter_list.c
./parameter_list.px $< > $#
This is just a general idea, your implementation may differ of course.
You may choose to generate ParameterList[] the same way or use [PARAM_ID_A_INDEX] = { ... } to make extra sure the indexes match.
Note the code above relies heavily on formatting, which may or may not be ok.
And in any case, some people may find tricks like this inappropriate.
Were I doing this, and I needed flexibility
Then I would have defined an enum that matches the table of data.
(no actual instance of the enum needed, just the definition
Then declared an array that contains some values from the enum.
The values in that array are the offsets into the data array
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 1 year ago.
Improve this question
As they say, your learn coding techniques from others' code. I've been trying to understand couple of free stacks and they all have one thing in common: Structure of function pointers. I've following of questions related to this architecture.
Is there any specific reason behind such an architecture?
Does function call via function pointer help in any optimization?
Example:
void do_Command1(void)
{
// Do something
}
void do_Command2(void)
{
// Do something
}
Option 1: Direct execution of above functions
void do_Func(void)
{
do_Command1();
do_Command2();
}
Option 2: Indirect execution of above functions via function pointers
// Create structure for function pointers
typedef struct
{
void (*pDo_Command1)(void);
void (*pDo_Command2)(void);
}EXECUTE_FUNC_STRUCT;
// Update structure instance with functions address
EXECUTE_FUNC_STRUCT ExecFunc = {
do_Command1,
do_Command2,
};
void do_Func(void)
{
EXECUTE_FUNC_STRUCT *pExecFunc; // Create structure pointer
pExecFun = &ExecFunc; // Assign structure instance address to the structure pointer
pExecFun->pDo_Command1(); // Execute command 1 function via structure pointer
pExecFun->pDo_Command2(); // Execute command 2 function via structure pointer
}
While Option 1 is easy to understand and implement, why do we need to use Option 2?
While Option 1 is easy to understand and implement, why do we need to use Option 2?
Option 1 doesn't allow you to change the behavior without changing the code - it will always execute the same functions in the same order every time the program is executed. Which, sometimes, is the right answer.
Option 2 gives you the flexibility to execute different functions, or to execute do_Command2 before do_Command1, based decisions at runtime (say after reading a configuration file, or based on the result of another operation, etc.).
Real-world example from personal experience - I was working on an application that would read data files generated from Labview-driven instruments and load them into a database. There were four different instruments, and for each instrument there were two types of files, one for calibration and the other containing actual data. The file naming convention was such that I could select the parsing routine based on the file name. Now, I could have written my code such that:
void parse ( const char *fileName )
{
if ( fileTypeIs( fileName, "GRA" ) && fileExtIs( fileName, "DAT" ) )
parseGraDat( fileName );
else if ( fileTypeIs( fileName, "GRA" ) && fileExtIs ( fileName, "CAL" ) )
parseGraCal( fileName );
else if ( fileTypeIs( fileName, "SON" ) && fileExtIs ( fileName, "DAT" ) )
parseSonDat( fileName );
// etc.
}
and that would have worked just fine. However, at the time, there was a possibility that new instruments would be added later and that there may be additional file types for the instruments. So, I decided that instead of a long if-else chain, I would use a lookup table. That way, if I did have to add new parsing routines, all I had to do was write the new routine and add an entry for it to the lookup table - I didn't have to modify any of the main program logic. The table looked something like this:
struct lut {
const char *type;
const char *ext;
void (*parseFunc)( const char * );
} LUT[] = { {"GRA", "DAT", parseGraDat },
{"GRA", "CAL", parseGraCal },
{"SON", "DAT", parseSonDat },
{"SON", "CAL", parseSonCal },
// etc.
};
Then I had a function that would take the file name, search the lookup table, and return the appropriate parsing function (or NULL if the filename wasn't recognized):
void (*parse)(const char *) = findParseFunc( LUT, fileName );
if ( parse )
parse( fileName );
else
log( ERROR, "No parsing function for %s", fileName );
Again, there's no reason I couldn't have used the if-else chain, and in retrospect it's probably what I should have done for that particular app1. But it's a really powerful technique for writing code that needs to be flexible and responsive.
I suffer from a tendency towards premature generalization - I'm writing code to solve what I think will be issues five years from now instead of the issue today, and I wind up with code that tends to be more complex than necessary.
Best explained via Example.
Example 1:
Lets say you want to implement a Shape class with a draw() method, then you would need a function pointer in order to do that.
struct Shape {
void (*draw)(struct Shape*);
};
void draw(struct Shape* s) {
s->draw(s);
}
void draw_rect(struct Shape *s) {}
void draw_ellipse(struct Shape *s) {}
int main()
{
struct Shape rect = { .draw = draw_rect };
struct Shape ellipse = { .draw = draw_ellipse };
struct Shape *shapes[] = { &rect, &ellipse };
for (int i=0; i < 2; ++i)
draw(shapes[i]);
}
Example 2:
FILE *file = fopen(...);
FILE *mem = fmemopen(...); /* POSIX */
Without function pointers, there would be no way to implement a common interface for file and memory streams.
Addendum
Well, there is another way. Based on the Shape example:
enum ShapeId {
SHAPE_RECT,
SHAPE_ELLIPSE
};
struct Shape {
enum ShapeId id;
};
void draw(struct Shape *s)
{
switch (s->id) {
case SHAPE_RECT: draw_rect(s); break;
case SHAPE_ELLIPSE: draw_ellipse(s); break;
}
}
The advantage of the second example could be, that the compiler could inline the functions, then you would have omitted the overhead of a function call.
"Everything in computer science can be solved with one more level of indirection."
The struct-of-function-pointers "pattern", let's call it, permits runtime choices. SQLite uses it all over the place, for example, for portability. If you provide a "file system" meeting its required semantics, then you can run SQLite on it, with Posix nowhere in sight.
GnuCOBOL uses the same idea for indexed files. Cobol defines ISAM semantics, whereby a program can read a record from a file by specifying a key. The underlying name-value store can be provided by several (configurable) libraries, which all provide the same functionality, but use different names for their "read a record" function. By wrapping these up as function pointers, the Cobol runtime support library can use any of those key-value systems, or even more than one at the same time (for different files, of course).
I need to code an automata, and I bumped into this old need of a computed goto (ala fortran4 :) )
I need to code this in a portable ansi-C.
I want to stay away from the "don't do that", away from longjmp/setjmp, away from embedded ASM(), away from non ansi-C extensions.
Does anyone know how to do this?
Like I said in a comment, despite your plea to not use anything other than goto, standard C has nothing to offer.
Design your state appropriately, and pass a pointer to it to the handler functions for them to modify. That way the handler can setup the next function to call. Something like this:
struct state;
typedef void state_func(struct state*);
#define NULL_ACTION_ADDRESS (state_func*)0
struct state {
state_func *action;
int value1;
int value2;
};
#define INIT_STATE { initial_action, -1, -1}
state_func initial_action;
state_func handle_a;
state_func handle_b;
int main(void) {
struct state s = INIT_STATE;
while(s.action != NULL_ACTION_ADDRESS) {
(*s.action)(&s);
}
return 0;
}
void initial_action(struct state* ps) {
ps->action = &handle_a;
}
void handle_a(struct state* ps) {
ps->action = &handle_b;
}
void handle_b(struct state* ps) {
ps->action = NULL_ACTION_ADDRESS;
}
I think I got it, I reviewed all the various threads on this topics and I started to agree that that there where no ansi C solutions, yet I found an way to do this that fit my needs. All solution I saw on stackoverflow where based on the idea to 'get' the addr of a label, then stuff it into a table, then index this table and goto, this is both with gcc/clang non ansi extension or the asm extension.
I gave it another try tonite and got this.
In an include file named cgoto.h I have this
#ifndef CGOTO_dcl
#define CGOTO_dcl(N) int CGOTO_##N
#define CGOTO_LE(l) l,
#define CGOTO_LG(l) case l:goto l;
#define CGOTO_def(N) \
if(0){typedef enum {N(CGOTO_LE)} N; CGOTO_##N: switch(CGOTO_##N)\
{N(CGOTO_LG) default:CGOTO_##N=0;goto CGOTO_##N;}}
#define CGOTO(N,i) CGOTO_##N=i; goto CGOTO_##N;
#endif
The usage is like this
#include <stdio.h>
#include "cgoto.h"
int f(int x)
{ //...
CGOTO_dcl(gtb);
//...
# define gtb(L) L(l0) L(l1) L(l2)
CGOTO_def(gtb);
//...
CGOTO(gtb,x);
l0: printf("error\n");
return(0);
//...
l1:return(11);
l2:return(22);
l3:return(33);
}
int main()
{ printf("f(0)=%d f(1)=%d f(2)=%d,f(3)=%d\n",f(0),f(1),f(2),f(3));
}
In this implementation, the cost of jumping is 2 jumps and a switch() that is sequential, then optimisable. So this is reasonably performing compared to function call, a little less performing than &&label solution at the cost of portability.
With this implementation, labels code (semantic actions) are not confined into a switch() so we can implement jump table with shared semantic actions.
The index is assigned to a local goto_table_index, making the function using this re-entrant (multi threadable), though the optimiser can remove altogether this temp assignment.
The 1st Label in a jump table is 'special' (on this implementation) in the sense that it catch index out of bound, the first label is the 'error' label. If your code is bullet proof, i.e there is no way you can get an out of bound index, then the 1st label has not particular semantic.
CGOTO_dcl(gtb);
Declare the jump table 'gtb' own index as an auto integer so reentrant.
# define gtb(L) L(l0) L(l1) L(l2)
CGOTO_def(gtb);
Define a jump table named gtb, labels can be entered/removed with L(label) so it is pretty convenient, and this is symbolic by nature, i.e the labels are name with a meaning. With #define as a switch() case, labels addition/suppression often mean #define renumbering that is a problem.
The #define can be separated from the CGOTO_def() but it make more sense to keep them together. The CGOTO_def() though got to be placed after the function local declaration as it contain a switch() that is code.
A uniq jump table can be used in multiple place in the function.
CGOTO(gtb,x);
...
CGOTO(gtb,y);
A label may be entered in multiple jump table
# define gtb1(L) L(l0) L(l1) L(l2)
CGOTO_def(gtb1);
# define gtb2(L) L(l0) L(l4) L(l5)
CGOTO_def(gtb2);
So all in all, this may looks ugly, yet, the jump table definition though 2 line the #define and the CGOTO_def() is manageable and practical, semi performant, and portable.
We are back to FTN4 :)
Cheers,
Phi
I'm wondering if the following is possible:
I have a namespace-style struct setup, filled with just function pointers. These are provided in the header file like so:
typedef struct {
int32_t(*const event_construct)(struct sync_event* evt);
int32_t(*const event_destroy)(struct sync_event* evt);
int32_t(*const event_set)(struct sync_event* evt);
int32_t(*const event_wait)(struct sync_event* evt);
} namespace_sync;
extern namespace_sync const sync;
and then in the relevant source file, after all the function implementations:
...
namespace_sync const sync = {
sync_event_construct,
sync_event_destroy,
sync_event_set,
sync_event_wait
};
Say I want to add an extra function not at the end; I add it to the struct and source file, but forget to assign it. Because the function declarations match, a warning isn't generated for it, and the compiler (at least in this example, vs2013) doesn't provide a hint that there's an issue.
I've got compile-time assertion checks available, but not sure if I can verify this particular aspect, since the struct size is accurate. If vs2013 can't work with it - I'm aware it's an abysmal C compiler(!) - the newest versions of gcc will also be used, so I could limit the functionality to one compiler.
One solution going forward would be to use designated initializers:
namespace_sync const sync = {
.event_construct = sync_event_construct,
.event_destroy = sync_event_destroy,
.event_set = sync_event_set,
.event_wait = sync_event_wait
};
Any unlisted members will default to null pointers.
I would advise to not add members into the middle of a struct, because it is difficult to be sure that you have correctly updated any code that was relying on the old struct layout. However, if you really do want to do this, then one way to have the compiler indicate to you where all the uses of the struct are is to change the struct name:
typedef struct {
// ...
} namespace_sync_2;
Then the code namespace_sync const sync will cause a compilation error. This alerts you to the fact that this piece of code requires a code review to make sure that it will work correctly with the new struct layout.
I have multiple header files, each of them must append a number to an array to register it's functions.
Currently I have a function with a unique name in each header file, and in the program file I need to call all those functions in one combining function.
int register1() { return 100; }; //in header1.h
int register2() { return 200; }; //in header2.h
int register3() { return 300; }; //in header3.h
int register4() { return 400; }; //in header4.h
int registered[] = {register1(),register2(),register3(),register4()}; //main.c
But this is quite inconvenient because I need to modify in two places when I add or remove header files. Better would be to modify the header file only. I was thinking about a preprocessor define, so in each header I can just use something like:
#define Registered Registered,100 // header1.h
#define Registered Registered,200 // header2.h
int registered[] = {Registered}; // main.c
But this of course will not compile, because new define redefines the old one. So is there a way to append a define? Or other way to append a number to an array without modifying two files?
This is C, not C++, otherwise I would use a class instance with constructor that would just write to an array. Somethink like that:
struct __header1{ __header1() {
global_array[global_array_ptr++] = 100;
} } __header1_inst;
and then convert it to a nice macro:
#define register(hdr, func) struct __header##hdr{ __header##hdr() { \
global_array[global_array_ptr++] = func; \
} } __header##hdr##_inst;
register(1, 100) // header1.h
register(2, 200) // header2.h
IMHO, this is a hack and I would advise against it. Even if you could do that in C, consider situation where one such header file is included by several modules. There will be an identical entry in the global array for every such module. Next, even though you can do it in C++, the order of global object initialization is undefined there, so initialization of another global object relying on contents of the global array will be unreliable.
Additionally, this is a really complicated way to do a simple thing, and obscures the meaning considerably. Apart from the array-filling code itself being complex, tracking includes will become burdensome when dependencies get beyond trivial. So, just fill that global array in a specific place explicitly.
I was trying to write a small debug utility and for this I need to get the function/global variable address given its name. This is built-in debug utility, which means that the debug utility will run from within the code to be debugged or in plain words I cannot parse the executable file.
Now is there a well-known way to do that ? The plan I have is to make the .debug_* sections to to be loaded into to memory [which I plan to do by a cheap trick like this in ld script]
.data {
*(.data)
__sym_start = .;
(debug_);
__sym_end = .;
}
Now I have to parse the section to get the information I need, but I am not sure this is doable or is there issues with this - this is all just theory. But it also seems like too much of work :-) is there a simple way. Or if someone can tell upfront why my scheme will not work, it ill also be helpful.
Thanks in Advance,
Alex.
If you are running under a system with dlopen(3) and dlsym(3) (like Linux) you should be able to:
char thing_string[] = "thing_you_want_to_look_up";
void * handle = dlopen(NULL, RTLD_LAZY | RTLD_NOLOAD);
// you could do RTLD_NOW as well. shouldn't matter
if (!handle) {
fprintf(stderr, "Dynamic linking on main module : %s\n", dlerror() );
exit(1);
}
void * addr = dlsym(handle, thing_string);
fprintf(stderr, "%s is at %p\n", thing_string, addr);
I don't know the best way to do this for other systems, and this probably won't work for static variables and functions. C++ symbol names will be mangled, if you are interested in working with them.
To expand this to work for shared libraries you could probably get the names of the currently loaded libraries from /proc/self/maps and then pass the library file names into dlopen, though this could fail if the library has been renamed or deleted.
There are probably several other much better ways to go about this.
edit without using dlopen
/* name_addr.h */
struct name_addr {
const char * sym_name;
const void * sym_addr;
};
typedef struct name_addr name_addr_t;
void * sym_lookup(cost char * name);
extern const name_addr_t name_addr_table;
extern const unsigned name_addr_table_size;
/* name_addr_table.c */
#include "name_addr.h"
#define PREMEMBER( X ) extern const void * X
#define REMEMBER( X ) { .sym_name = #X , .sym_addr = (void *) X }
PREMEMBER(strcmp);
PREMEMBER(printf);
PREMEMBER(main);
PREMEMBER(memcmp);
PREMEMBER(bsearch);
PREMEMBER(sym_lookup);
/* ... */
const name_addr_t name_addr_table[] =
{
/* You could do a #include here that included the list, which would allow you
* to have an empty list by default without regenerating the entire file, as
* long as your compiler only warns about missing include targets.
*/
REMEMBER(strcmp),
REMEMBER(printf),
REMEMBER(main),
REMEMBER(memcmp),
REMEMBER(bsearch),
REMEMBER(sym_lookup);
/* ... */
};
const unsigned name_addr_table_size = sizeof(name_addr_table)/sizeof(name_addr_t);
/* name_addr_code.c */
#include "name_addr.h"
#include <string.h>
void * sym_lookup(cost char * name) {
unsigned to_go = name_addr_table_size;
const name_addr_t *na = name_addr_table;
while(to_to) {
if ( !strcmp(name, na->sym_name) ) {
return na->sym_addr;
}
na++;
to_do--;
}
/* set errno here if you are using errno */
return NULL; /* Or some other illegal value */
}
If you do it this way the linker will take care of filling in the addresses for you after everything has been laid out. If you include header files for all of the symbols that you are listing in your table then you will not get warnings when you compile the table file, but it will be much easier just to have them all be extern void * and let the compiler warn you about all of them (which it probably will, but not necessarily).
You will also probably want to sort your symbols by name such that you can use a binary search of the list rather than iterate through it.
You should note that if you have members in the table which are not otherwise referenced by the program (like if you had an entry for sqrt in the table, but didn't call it) the linker will then want (need) to link those functions into your image. This can make it blow up.
Also, if you were taking advantage of global optimizations having this table will likely make those less effective since the compiler will think that all of the functions listed could be accessed via pointer from this list and that it cannot see all of the call points.
Putting static functions in this list is not straight forward. You could do this by changing the table to dynamic and doing it at run time from a function in each module, or possibly by generating a new section in your object file that the table lives in. If you are using gcc:
#define SECTION_REMEMBER(X) \
static const name_addr_t _name_addr##X = \
{.sym_name= #X , .sym_addr = (void *) X } \
__attribute__(section("sym_lookup_table" ) )
And tack a list of these onto the end of each .c file with all of the symbols that you want to remember from that file. This will require linker work so that the linker will know what to do with these members, but then you can iterate over the list by looking at the begin and end of the section that it resides in (I don't know exactly how to do this, but I know it can be done and isn't TOO difficult). This will make having a sorted list more difficult, though. Also, I'm not entirely certain initializing the .sym_name to a string literal's address would not result in cramming the string into this section, but I don't think it would. If it did then this would break things.
You can still use objdump to get a list of the symbols that the object file (probably elf) contains, and then filter this for the symbols you are interested in, and then regenerate the table file the table's members listed.