I need some help rewriting the following line in a more type safe way and rewriting it as a function, however the fact that this code is defined inside a function is making it hard for me to think of a clever way of doing it because apparently it would involve declaring several arguments.
#define CHECK(id) if(table->cells[id]) isgood[table->cells[id]-1] = 0;
where table is a struct and isgood is an int.
Straight translation (if table->cells[id] is int):
void check(int id, int*isgood) { if (id) isgood[id-1] = 0; }
Call with:
check(table->cells[id], isgood);
However, I'd rename/rework this a bit. I'd especially change the name. There is also no error checking - ie, if table->cells[id]==0, you're going to try to set isgood[-1], which would be bad.
apparently it would involve declaring
several arguments
What is wrong with that?
Why not just a function that receives table and id and does this?
void foo(TableType & t, int id)
{
if (t.cells[id])
isgood[t.cells[id]-1] = 0;
}
p.s.
It's a bad macro indeed. The name is very misleading.
p.p.s.
The whole thing is rather weird and the logic of this function escapes me. What exactly is this supposed to achieve?
If you're working in C++, I'd consider making check a member function of the table, which seems like a good candidate for a class:
class Table {
//...
public bool check(int id) {
if (this->cells[id]) {
this->isGood[id] = 0;
// the line you have, isgood[table->cells[id]-1] = 0 looks buggy:
// you treat table->cells[id] as a true/false value one line ago;
// probably not a valid array index? I'm taking a stab at what to do.
}
}
}
It is generally a good idea not to refer to variables in a macro.
First, make sure the name is meaningful. what are you checking for? And is there a side effect?
void update_valid_cells(Table& table, int id, BoolArray& validArray)
{
if(table.cells[id]==NULL) return;
validArray[id]-1=false;
}
I think C99 can qualify functions as inline so you get the speedup of no-function-call without using macros. Also, most C compilers support extensions such as __inline for this purpose.
Related
Hey I am currently trying to switch from c++ to c and wonder if there is any way to avoid this because there are no more classes to use the implicit this->:
void func(Data *const longAndExpressiveName)
{
longAndExpressiveName->x += longAndExpressiveName->vel.x;
}
Because even if the name is not that long it still makes the code much harder to understand.
There is no syntax to accomplish your direct ask in C. The closest you can come is to create temporary variables.
int *xptr = &longAndExpressiveName->x;
int vel_x = longAndExpressiveName->vel.x;
*xptr += vel_x;
Your desire to use longAndExpressiveName is misplaced in this case, because in C++, you are coming from a syntax where longAndExpressiveName is not passed as a parameter, and the parameter is implicitly hidden by the implicit this->. The C++ syntax for the caller would be:
longAndExpressiveName->func();
And you are translating that into:
func(longAndExpressiveName);
And then you propagate that same name to the parameter name. While it may be appropriate for the caller to refer to the pointer with a long and expressive name, it is not really helpful to the "member" function. But, what would be helpful is if the function is named so that you know it is meant to do something to a particular kind of structure.
void func_Data(Data * const d) {
d->x += d->vel.x;
}
Which better captures the original C++ syntax:
void Data::func () {
x += vel.x;
}
C does not have any magic syntax to do what you want explicitly. However, you can just assign the parameter with a long and expressive name to a variable of the same or compatible type with a shorter name:
void func(Data *const longAndExpressiveName)
{
Data *const t = longAndExpressiveName;
t->x += t->vel.x;
}
This cuts down on typing if the long and expressive name would otherwise be repeated a lot in the function.
i want to concatenate a lot of macros in order to pass them as parameter in a struck array. to be more specific i have this struct
static struct
{
unsigned int num_irqs;
volatile __int_handler *_int_line_handler_table;
}_int_handler_table[INTR_GROUPS];
and I want to pass as num_irqs parameter a series of macros
AVR32_INTC_NUM_IRQS_PER_GRP1
AVR32_INTC_NUM_IRQS_PER_GRP2
...
first I thought to use this code
for (int i=0;i<INTR_GROUPS;i++)
{
_int_handler_table[i].num_irqs = TPASTE2(AVR32_INTC_NUM_IRQS_PER_GRP,i);
}
but it takes the i as char and not the specific value each time. I saw also that there is a MREPEAT macro defined in the preprocessor.h but I do not understand how it is used from the examples.
Can anyone can explain the use of MREPEAT or another way to do the above.
Keep in mind the preprocessor (which manipulates macros) runs before the compiler. It's meant to manipulate the final source code to be submitted to the compiler.
Hence, it has no idea of what value has a variable. For the preprocessor, i means i.
What you try to do is a bit complex, especially keeping in mind that preprocessor cannot generate preprocessor directives.
But it can generate constants.
Speaking of which, for your use case, I would prefer to use a table of constants, such as :
const int AVR32_INTC_NUM_IRQS_PER_GRP[] = { 1, 2, 3, 4, 5 };
for (int i=0;i<INTR_GROUPS;i++)
{
_int_handler_table[i].num_irqs = TPASTE2(AVR32_INTC_NUM_IRQS_PER_GRP[i]);
}
C doesn't work like that.
Macros are just text-replacement which happens att compile-time. You can't write code to construct a macro name, that doesn't make sense. The compiler is no longer around when your code runs.
You probably should just do it manually, unless the amount of code is very large (in which case code-generation is a common solution).
I am a novice programmer exploring the depths of C. Why does some inbuilt functions return a const value ? Can somebody explain the benefits or drawbacks of using const in method returns ?
Using final and const in returning values from functions and methods is to keep people from changing their values. For example, if i had (in c)
char* getChar()
{
return "string";
}
and I didn't want someone to use it like
char myChar = getChar()[0]++;
then i would have to return a const, to keep it from being changed.
For Java, it's very different. You don't return final values, you make methods final.
final is used with a Java method to mark that the method can't be overridden (for object scope) or hidden (for static). This allows the original developer to create functionality that he can be sure will not be changed by others, and that is all the guarantee it provides.
C's const and Java's final are very different, and especially in the case you're talking about.
In C (disclaimer: I haven't done C in a while so please let me know where I'm wrong) let's look at this example:
const int something() {
return 3;
}
The const is meaningless because it's not like you can do:
something() = 3;
For some more information on const return values in C, take a look at the following:
const makes no sense for return values...
Purpose of returning by const value (this is C++, but still useful).
In Java, I'm assuming you're talking about something like:
public final int something() {
...
}
Here final has nothing to do with the return value. final here means that if you extend the class that something() belongs to, you cannot override the implementation of something(). This is somewhat similar in spirit to final variables; these are variables whose values you cannot change once they are set.
Mostly for fun, I've decided to write my own minimal test framework for my C code. I use a basic struct for the test information, create an array of test structs and then iterate over them to run all the tests. This amounts to a very small amount of work for a fairly elegant (imho) solution.
However, the one thing that is a little annoying is that I cannot figure out how to define functions as function pointers instead of defining the function and then creating a function pointer later.
I have the following (which works just fine):
typedef int (* test_p) (void);
struct test {
char * desc;
test_p func;
};
int
example_test (void) {
puts("This is a test");
return 0;
}
void
run_test (char * test_name, test_p test) {
printf("Testing %s\t\t\t[ PEND ]\r", test_name);
char * test_result = (test() ? "FAIL" : "PASS");
printf("Testing %s\t\t\t[ %s ]\n", test_name, test_result);
}
int
main (void) {
struct test test_list [] = {
{ "example test", (test_p )example_test }
};
for ( int i = 0; i < 1; i ++ ) {
run_test(test_list[i].desc, test_list[i].func);
}
return 0;
}
However, I am hoping I can remove the need for the casting in the struct and instead define the function as being a function pointer from the beginning. The following is an example of how I would like this to work (assuming many of the same things as above):
test_p
example_test = {
puts("This is a test");
return 0;
}
If I could do something like this, then in the struct, I could simply have the func field be example_test rather than (test_p )example_test. Is this (or something like it) possible? If not, is there a reason why not (If that reason is simply "because it wasn't added to the language", that's fine)?
A function pointer is one kind of thing and a function is another kind of thing so you can't really make the latter be the former. But if you use a function name where a function pointer is expected, that produces a pointer to the function, so you can just remove the unnecessary cast, as WhozCraig said in the first comment above. You write
If I could do something like this, then in the struct, I could simply have the func field be example_test rather than (test_p )example_test.
You can do that, with example_test defined just as it is in your current code ... did you try that?
You can also forward declare a function, like so:
typedef int test_func(void); // note no indirection
typedef test_func* test_p;
test_func example_test;
It would be nice if you could use that sort of syntax when you define the function, as in your attempted syntax, but there's simply no way to do that in C ... you have to explicitly provide the return type and parameter list.
Another detail is that, when you invoke the function pointed to by a function pointer, you don't have to dereference it ... that's why you were able to write
test()
instead of
(*test)()
although the latter also works. (In fact, because the deference is stripped, (********test)() also works ... but only do that if you're trying to win an obfuscation contest.)
What you are describing is a kind of meta-programming. Rather than writing code to explicitly solve the problem, you are concerned with a kind of syntactic structure that will allow you to define a whole raft of test functions without unnecessary cruft.
In Lisp you would use macros. In C++ you might use templates and/or lambdas. In C you use macros.
So you need to write a macro that:
takes a name and descriptive text as arguments
defines a static variable of type function (created from that name using token pasting)
defines a function (using a name created by token pasting)
[edit] At this point you have achieved the goal: you have created the function and given it a name that is (only) a function pointer, and you can use that name in your struct without a cast. I would suggest one additional step, the macro also:
adds the variable/function and descriptive text to a list of functions to be tested.
Then your boilerplate loop iterates over the structure calling each function and reporting the results using the descriptive text. Problem solved.
Some people don't like macros, but they are ideally suited to this situation, and there is no other way to do it in C. I did something just like this before making the move to C++.
I'm trying to understand callbacks, and do get the idea, but do not understand why it is really needed.
Specifically, what added benefit does it provide over a normal function call? I'm looking at the accepted answer here : What is a "callback" in C and how are they implemented?
I have redone the same thing below, just without using function pointers. How is that different from this?
void populate_array(int *array, size_t arraySize)
{
for (size_t i=0; i<arraySize; i++)
array[i] = getNextRandomValue();
}
int getNextRandomValue(void)
{
return rand();
}
int main(void)
{
int myarray[10];
populate_array(myarray, 10);
...
}
Is it only beneficial if lower-layer software needs to call a function that was defined at a higher-layer?
This implementation is different in that the only way it knows to populate the array is hard-coded: getNextRandomValue is the way it populates the array, and it is part of the library that provides the populate_array functionality. Essentially, the two functions are baked together into a single whole (the fancy way of saying the same thing is to say that they are "tightly coupled").
With the original implementation I can do all of the things below without changing a line in the populate_array:
int getNextRandomValue(void) {
return rand();
}
int getNextEvenValue(void) {
static int even = 2;
return (even += 2);
}
int getNextNegativeValue(void) {
static int neg = -1;
return neg--;
}
int getNextValueFromUser(void) {
int val;
scanf("%d", &val);
return val;
}
populate_array(myarray, 10, getNextRandomValue);
populate_array(myarray, 10, getNextEvenValue);
populate_array(myarray, 10, getNextNegativeValue);
populate_array(myarray, 10, getNextValueFromUser);
With your implementation I would have to write a separate populate_array for each of these cases. If the way of populating an array that I need is not part of the library, I am on the hook for implementing the whole populate_array, not only its value-producing generator function. This may not be that bad in this case, but in cases where callbacks really shine (threads, asynchronous communications) reimplementing the original without callbacks would be prohibitive.
In your example, getNextRandomValue must be known at compile time. This means that you cannot reuse the function with different definitions of getNextRandomValue, neither let other users link to your code and specify their version of getNextRandomValue. Note that this is not a callback, rather a "generic" function: think of getNextRandomValue as a placeholder for a function.
Callbacks are a special use of "generic" functions: they are called upon completion of an asynchronous task, to notify the user of the operation results (or progress).
I don't think that function pointers only suit low-to-high-level communication. Function pointers, as said, allow you to build generic code in C. A quick example, qsort(): order sorting needs a function that, given a and b, tells whether a>b, a<b or a==b, so that a and b can be placed in the right order. Well, qsort let you provide your own definition for order, thus offering a general, reusable piece of code.
To refine other answers here: Your function populate_array has a bad name. It should be named populate_array_with_random_values.
As said in the answer you linked to "there is no callback in c". There only is a method to pass pointers to function to a function.
Which is useful in general not only for lower-layer software that needs to call a function on a higher-level though this might be often how it is used.
Passing function pointers as parameters is an elegant way to write code. In your example if you want to have two variations on how to get the next random value you already see how it is much easier to pass the function as a parameter rather then trying to pass a parameter that then selects the next function to call using a switch.