Designing Around a Large Number of Discrete Functions in C - c

Greetings and salutations,
I am looking for information regrading design patterns for working with a large number of functions in C99.
Background:
I am working on a complete G-Code interpreter for my pet project, a desktop CNC mill. Currently, commands are sent over a serial interface to an AVR microcontroller. These commands are then parsed and executed to make the milling head move. a typical example of a line might look like
N01 F5.0 G90 M48 G1 X1 Y2 Z3
where G90, M48, and G1 are "action" codes and F5.0, X1, Y2, Z3 are parameters (N01 is the optional line number and is ignored). Currently the parsing is coming along swimmingly, but now it is time to make the machine actually move.
For each of the G and M codes, a specific action needs to be taken. This ranges from controlled motion to coolant activation/deactivation, to performing canned cycles. To this end, my current design features a function that uses a switch to select the proper function and return a pointer to that function which can then be used to call the individual code's function at the proper time.
Questions:
1) Is there a better way to resolve an arbitrary code to its respective function than a switch statement? Note that this is being implemented on a microcontroller and memory is EXTREMELY tight (2K total). I have considered a lookup table but, unfortunately, the code distribution is sparse leading to a lot of wasted space. There are ~100 distinct codes and sub-codes.
2) How does one go about function pointers in C when the names (and possibly signatures) may change? If the function signatures are different, is this even possible?
3) Assuming the functions have the same signature (which is where I am leaning), is there a way to typedef a generic type of that signature to be passed around and called from?
My apologies for the scattered questioning. Thank you in advance for your assistance.

1) Perfect hashing may be used to map the keywords to token numbers (opcodes) , which can be used to index a table of function pointers. The number of required arguments can also be put in this table.
2) You don's want overloaded / heterogeneous functions. Optional arguments might be possible.
3) your only choice is to use varargs, IMHO

I'm not an expert on embedded systems, but I have experience with VLSI. So sorry if I'm stating the obvious.
The function-pointer approach is probably the best way. But you'll need to either:
Arrange all your action codes to be consecutive in address.
Implement an action code decoder similar to an opcode decoder in a normal processor.
The first option is probably the better way (simple and small memory footprint). But if you can't control your action codes, you'll need to implement a decoder via another lookup table.
I'm not entirely sure on what you mean by "function signature". Function pointers should just be a number - which the compiler resolves.
EDIT:
Either way, I think two lookup tables (1 for function pointers, and one for decoder) is still going to be much smaller than a large switch statement. For varying parameters, use "dummy" parameters to make them all consistent. I'm not sure what the consequences of force casting everything to void-pointers to structs will be on an embedded processor.
EDIT 2:
Actually, a decoder can't be implementated with just a lookup table if the opcode space is too large. My mistake there. So 1 is really the only viable option.

Is there a better way ... than a switch statement?
Make a list of all valid action codes (a constant in program memory, so it doesn't use any of your scarce RAM), and sequentially compare each one with the received code. Perhaps reserve index "0" to mean "unknown action code".
For example:
// Warning: untested code.
typedef int (*ActionFunctionPointer)( int, int, char * );
struct parse_item{
const char action_letter;
const int action_number; // you might be able to get away with a single byte here, if none of your actions are above 255.
// alas, http://reprap.org/wiki/G-code mentions a "M501" code.
const ActionFunctionPointer action_function_pointer;
};
int m0_handler( int speed, int extrude_rate, char * message ){ // M0: Stop
speed_x = 0; speed_y = 0; speed_z = 0; speed_e = 0;
}
int g4_handler ( int dwell_time, int extrude_rate, char * message ){ // G4: Dwell
delay(dwell_time);
}
const struct parse_item parse_table[] = {
{ '\0', 0, unrecognized_action } // special error-handler
{ 'M', 0, m0_handler }, // M0: Stop
// ...
{ 'G', 4, g4_handler }, // G4: Dwell
{ '\0', 0, unrecognized_action } // special error-handler
}
ActionFunctionPointer get_action_function_pointer( char * buffer ){
char letter = get_letter( buffer );
int action_number = get_number( buffer );
int index = 0;
ActionFunctionPointer f = 0;
do{
index++;
if( (letter == parse_table[index].action_letter ) and
(action_number == parse_table[index].action_number) ){
f = parse_table[index].action_function_pointer;
};
if('\0' == parse_table[index].action_letter ){
index = 0;
f = unrecognized_action;
};
}while(0 == f);
return f;
}
How does one go about function pointers in C when the names (and
possibly signatures) may change? If the function signatures are
different, is this even possible?
It's possible to create a function pointer in C that (at different times) points to functions with more or less parameters (different signatures) using varargs.
Alternatively, you can force all the functions that might possibly be pointed to by that function pointer to all have exactly the same parameters and return value (the same signature) by adding "dummy" parameters to the functions that require fewer parameters than the others.
In my experience, the "dummy parameters" approach seems to be easier to understand and use less memory than the varargs approach.
Is there a way to typedef a generic type of that signature
to be passed around and called from?
Yes.
Pretty much all the code I've ever seen that uses function pointers
also creates a typedef to refer to that particular type of function.
(Except, of course, for Obfuscated contest entries).
See the above example and Wikibooks: C programming: pointers to functions for details.
p.s.:
Is there some reason you are re-inventing the wheel?
Could maybe perhaps one of the following pre-existing G-code interpreters for the AVR work for you, perhaps with a little tweaking?
FiveD,
Sprinter,
Marlin,
Teacup Firmware,
sjfw,
Makerbot,
or
Grbl?
(See http://reprap.org/wiki/Comparison_of_RepRap_Firmwares ).

Related

Unpermitted operand to operator '++' [MISRA 2012 Rule 10.1, required]

I am trying to fix the Misra warning for the modules written by others. I observed that ++ operation is being used on the enum.
I referred SE question which talks on the same topic. How do I resolve this error? Do I need to suggest the module owner, to change the implementation?
#include <stdio.h>
typedef enum
{
COMPARE = 0,
INCONSISTENT = 10,
WRITE,
READ,
FINISHED
}TestsType;
static TestsType CurrentTest;
void fun1(void)
{
if(READ != CurrentTest)
{
CurrentTest++;
}
else
{
CurrentTest = FINISHED;
}
}
int main(void) {
// your code goes here
CurrentTest = COMPARE;
fun1();
printf("%d", CurrentTest);
return 0;
}
I kept the enum like this in code purposefully to understand any impact. However, in actual code, it is as below.
typedef enum
{
COMPARE,
INCONSISTENT,
WRITE,
READ,
FINISHED
}TestsType;
Incrementing an enum is just wrong!
enums were added to the language as a better alternative to #define for a number of constants, and were considered ints in other respects (i.e. a const array of ints). To enforce anything more would require run-time checking.
As enum values don't have to be contiguous, incrementing them makes no sense when they're treated as integers. If a compiler does allow it, it thinks it's incrementing an int, which can mean your value doesn't correspond to any value in the enum afterwards.
So my advice is "don't do it" even if a particular compiler lets you. Rewrite it to something explicit.
If you want to cycle through a particular range of states represented by contiguous integers, you CAN use an enum but only if you make its values contiguous too. Put lots of warnings about the definition explaining not to tinker. Then increment an int representing the state, which can then be compared to the enum safely.
The whole point of using a standard like MISRA is to avoid risky code. And there's no question but that incrementing enums is risky.
If you've got some code that increments enums, and it works well (under all conditions), it's only because of a number of interlocked assumptions and conventions which probably aren't all written down and which almost certainly won't be obvious to (and honored by) a later maintenance programmer.
So, indeed, there is no simple fix for this. Any simple fix (which might get your MISRA checker to shut up) will likely leave the inherent risks in the practice all intact -- that is, you might satisfy the letter of MISRA, but not the spirit (which is obviously backwards).
So yes, you should require (not just suggest) that the module owner change the implementation.
What might the revised implementation look like? I think it should have one or more of the following aspects:
Use an int and some #defined constants.
Have a separate, encapsulated function to map from one state to the next.
Use an explicit transition table to map one state to the next.
If there is a large number of states, and if most of them follow in sequence, such that a +1 increment would nicely encapsulate this (more cleanly and reliably than a bunch of arbitrary state transitions), go ahead and use a +1 increment, but with some accompanying assertions to ensure that the various assumptions hold. For example:
enum state {
OFF = 0,
LOW = 3,
MEDIUM,
HIGH,
EXCEPTIONAL = 10
};
/* States LOW..HIGH are assumed to be contiguous. Make sure you keep them so! */
/* If (and only if) you add or subtract states to the contiguous list, */
/* make sure to also update N_CONTIGUOUS_STATES. */
#define N_CONTIGUOUS_STATES 3
enum state nextstate(enum state oldstate)
{
/* Normally performing arithmetic on enums is wrong. */
/* We're doing so here in a careful, controlled, constrained way, */
/* limited just to the values LOW..HIGH which we're calling "contiguous". */
assert((int)LOW + N_CONTIGUOUS_STATES - 1 == (int)HIGH);
if(oldstate >= LOW && oldstate < HIGH) {
return (enum state)((int)oldstate + 1);
} else {
/* perform arbitrary mappings between other states */
}
}
The intent here is both to document what's going on, and ensure that if a later maintenance programmer changes the enum definition in any way that breaks the assumption that there are some consecutive states between which straight incrementation is allowed, the assertion will fail.
...But I hasten to add that this is not a complete solution. An even more important guarantee to preserve is that every state transition is handled, and this is even easier to violate if a later maintenance programmer adds new states but forgets to update the transition mappings. One good way to have the compiler help you guarantee this is to use a switch statement, although this then just about forces you to make every transition explicit (that is, not to use the +1 shortcut):
enum state nextstate(enum state oldstate)
{
switch(oldstate) {
case OFF: return ... ;
case LOW: return MEDIUM;
case MEDIUM: return HIGH;
case HIGH: return ... ;
case EXCEPTIONAL: return ... ;
}
}
The advantage of using a switch is that modern compilers will warn you if you leave an enum value out of a switch like this.

Whether frama-c can get the range of variables before a particular program code

int main()
{
int B = 1;
int x = rand()%10+1;
int x1 = rand()%10+1;
int A = 1;
while((B <= 5))
{
B++;
A++;
if(B == x)
{
return 0;
}
}
task(A) //The variable A passes in the range of values before the task function
A = -2;
return 0;
}
/*How can I use frama-c to get the range of A at task code if I want to get the range of A at task statement position instead of the range of A at the end of the program execution*/
How can I use frama-c to get the range of A at task code if I want to get the range of A at task statement position instead of the range of A at the end of the program execution
If I understand your question well, you would like to know the interval of variation of A at a specific statement. I assume that you're are relying on the Eva plug-in, as it is the kind of information that is typically given by Eva (at least if I interpret well "instead of the range of A at the end of the program execution").
There are two possibilities. The first one is to use the programmatic API of Eva, namely the Db.Value module. This requires knowledge of OCaml and reading the Frama-C developer manual, but is the most flexible and stable way to access the information. Briefly speaking, Db.Value.get_state will, as its name suggests, return the abstract state computed after a run of the Eva analyzer, for the statement given as argument, while Db.Value.eval_expr, will, given an abstract state and an expression, compute the abstract value of the expression in the corresponding state.
The second possibility is to use the Frama_C_show_each_* family of built-in functions: whenever Eva encounters a function whose name starts with Frama_C_show_each_, it will print on the standard output the abstract value of the arguments given to the function in the current abstract state. Hence, adding Frama_C_show_each_A(A); before the call to task(A) will give you, with frama-c -eva test.i, among other things
[eva] test.i:19: Frama_C_show_each_A: [1..2147483647]
Note that I've modified your code in order to let it run properly with Frama-C:
added prototype extern int rand(void); and extern void task(int);
added a ';' after task(A)
Please ensure that you provide a minimal, complete and verifiable example with your questions, this makes them much, much, easier to answer

Should you check parameters passed into function before passing them, or check them in the function?

As a good practice, do you think one should verify passed parameters within a function to which the parameters are being passed, or simply make sure the function will always accept correct parameters?
Consider the following code:
Matrix * add_matrices(const Matrix * left, const Matrix * right)
{
assert(left->rowsCount == right->rowsCount
&& left->colsCount == right->colsCount);
int rowsCount = left->rowsCount;
int colsCount = left->colsCount;
Matrix * matOut = create_matrix(rowsCount, colsCount);
int i = 0;
int j = 0;
for (i; i < rowsCount; ++i)
{
for (j; j < colsCount; ++j)
{
matOut->matrix[i][j] = left->matrix[i][j] + right->matrix[i][j];
}
}
return matOut;
}
Do you think I should check the parameters before passing them to the function or after, ie. in the function? What is a better practice or is it programmer dependant?
Inside. The function can be viewed as an individual component.
Its author is best placed to define any preconditions and check them.
Checking them outside presupposes the caller knows the preconditions which may not be the case.
Also by placing them inside the function you're assured every call is checked.
You should also check any post-conditions before leaving the function.
For example if you have a function called int assertValid(const Matrix*matrix) that checks integrity of the object (e.g. the data is not a NULL pointer) you could call it on entry to all functions and before returning from functions that modify a Matrix.
Consistently use of pre- and post- condition integrity are an enormously effective way of ensuring quality and localising faults.
In practice zealous conformance to this rule usually results in unacceptable performance. The assert() macro or a similar conditional compilation construct is a great asset. See <assert.h>.
Depends if the function is global in scope or local static.
A global function cannot control what calls it. Defensive coding will perform validation of the arguments received. But how much validation to do?
int my_abs(int x) {
assert(x >= -INT_MAX);
return abs(x);
}
The above example, in a debug build, checks to insure the absolute value function will succeed as abs(INT_MIN) may be a problem. Now if this checking should be in production builds is another question.
int some_string(char *s) {
assert(s != NULL);
...
}
In some_string() the test for NULL-ness may be dropped as function definition may state that s must be a string. Even though NULL is not a C string, testing for NULL-ness is only 1 of many bad pointers that could be passed which do not point to a string. So this test has limited validation.
With static functions, the code is under local control. Argument validation could occur by the function, the caller, both or neither. That selection is code dependent.
A counter-example exist with user/file input. Basic data qualification should occur promptly.
int GetDriversAge(FILE *inf) {
int age;
if (fscanf("%d", &age) != 1) Handle_Error();
if (age < 16 || age > 122) Handle_Error();
return age
}
In OP's example, parameter checking is done by the function, not the caller. Without the equivalence test, the function can easily fail in mysterious ways. The cost of this check here is a small fraction of the code's work. That makes it a good check as expensive checks (time, complexity) can cause more trouble than they solve. Note that if the calling code did this test and add_matrices() was called from N places, then that checking code is replicated N times in various, perhaps, inconsistent ways.
Matrix * add_matrices(const Matrix * left, const Matrix * right) {
assert(left->rowsCount == right->rowsCount
&& left->colsCount == right->colsCount);
Conclusion: more compelling reasons to check the parameters in the function than in the caller though exceptions exist.
What I do is to check the parameters inside the function and act accordingly (throw exceptions, return error messages, etc.). I suppose it's the function's job to check whether the passed parameters are of the correct data type and contain valid values.
The function should perform its task correctly, otherwise, it should throw an exception. The client/consuming code may or may not do a check, it depends on the data source and how much you trust it, either way, you should also enclose the function call in a catch-try block to catch invalid argument exception.
EDIT:
Sorry, I confused C for C++. Instead of throwing an exception, you can return null. The client doesn't necessarily have to check the data before calling (depending on the data source and other factors like performance constraints), but must always check for null as a return value.

is it possible to write a program which prints its own source code utilizing a "sequence-generating-function"

is it possible to write a program which prints its own source code utilizing a "sequence-generating-function"?
what i call a sequence-generating-function is simply a function which returns a value out of a specific interval (i.e. printable ascii-charecters (32-126)). the point now is, that this generated sequence should be the programs own source-code. as you see, implementing a function which returns an arbitrary sequence is really trivial, but since the returned sequence must contain the implementation of the function itself it is a highly non-trivial task.
this is how such a program (and its corresponding output) could look like
#include <stdio.h>
int fun(int x) {
ins1;
ins2;
ins3;
.
.
.
return y;
}
int main(void) {
int i;
for ( i=0; i<size of the program; i++ ) {
printf("%c", fun(i));
}
return 0;
}
i personally think it is not possible, but since i don't know very much about the underlying matter i posted my thoughts here.
i'm really looking forward to hear some opinions!
If you know how to encode an array as a function (you seem to be saying you already know how to do this) then the Kleene Recursion theorem guarantees it can be done.
But for doubting Thomases, here's a C example. It has a program generating function that uses only +, -, *, / or calls other functions that use them.
Quines are always possible if you have Turing completeness and freedom to print what you like.
What you're referring to is a QUINE. Wiki's article on it is pretty good, with some helpful links. http://en.wikipedia.org/wiki/Quine_%28computing%29
To fly off at a tangent, try looking at Tupper's Self-Referential Formula.

what is the alternate way of doing function of switch-case (and if-else) in c?

what is the alternate way of doing function of switch-case (and if-else) in c?
Function pointers are one alternative. Consider the following snippet that calls a function through a function pointer array:
#include <stdio.h>
void fn0(int n) { printf ("fn0, n = %d\n",n); }
void fn1(int n) { printf ("fn1, n = %d\n",n); }
void fn2(int n) { printf ("fn2, n = %d\n",n); }
void fn3(int n) { printf ("fn3, n = %d\n",n); }
static void (*fn[])(int) = {fn0, fn1, fn2, fn3};
int main(void) {
int i;
for (i = 0; i < 4; i++)
fn[i](10-i);
return 0;
}
This generates:
fn0, n = 10
fn1, n = 9
fn2, n = 8
fn3, n = 7
This sort of construct makes it very easy to implement things such as finite state machines where, instead of a massive switch statement or near-unmanageable nested if's, you can just use an integer state variable to index into an array of function pointers.
You could always use gotos... :-p
Function pointers and a semi implementation of the strategy pattern :)
.. though youll need some logic to determine which function to call
There are several different ways to handle conditional branch-and-switch scenarios in C.
The typical patterns, which you yourself mention, are switch( ) statements and if/else if/else groups. However, sometimes these flow control constructs are not the best choice for certain problems. Specifically cases such as:
High performance branching over a large domain
Branching on value domains only known at runtime
Changing the branch paths at runtime based on other conditions
In these cases, there are two patterns that I find helpful:
The Strategy pattern with a direct dispatch
The Strategy pattern with a chained dispatch
In the first approach, you map each value from your domain to a collection of function pointers. Each function handles a particular case (value) from your domain. This allows you to "jump" directly to the right handler for a particular case. This pattern works well when each case is separated from all the others and there is little or no overlapping logic.
In the second approach, you chain all of the dispatch methods together - and call each of them for all cases. Each dispatched method decides if it handles the case or not, and either returns immediately or performs some processing. This pattern is useful when there is overlap between the responsibilities of some of the handlers. It is somewhat less performant, since multiple handlers are invoked, and each decides whether it needs to perform its processing. However, this is one of the easier ways to deal with overlapping logic - the kind you could normally handle in a switch() statement with fall through (or jump) conditions.
You should only use one of these techniques if the problem really requires it, since they are less obvious to future developers and can introduce unnecessary complexity and maintenance problems if implemented poorly. It also makes your code more difficult to understand, over more common constructs like switch or if/else.

Resources