For my systems programming class we're doing a lot of programming in C and are required to error check most functions as we are currently learning to program with pthreads.
The reason I say this is not really homework, is that it is far above and beyond what is expected for this class. Simply checking each function individually is more than satisfactory. I just feel this is a time-consuming and messy method and hope for a neater solution.
I was wondering if anyone could show me how to write a function that takes any C function as a parameter, followed by all the required parameters for that function, along with a desired return value (in this case the correct one), and performs the following.
if(function_name(param1, param2, ...) != desired_return_value) {
fprintf(stderr, "program_name: function_name() failed\n");
perror("function_name(): ");
}
Is this possible? It's hardly required by our course, but it just irks me that virtually ever function I write has to have 4 lines of code to error check it. It makes it bloody hard to read.
Even some other suggestions would be good. I'm just trying to increase readability, so if this is totally the wrong direction, some correct direction would be much appreciated.
EDIT: This should compile under the gnu99 standard ideally :P
EDIT 2: In response to James McNellis:
The errors from our functions do not (I believe in this case), need to be handled. Notification only needs to be supplied. We have covered nothing on handling thread/process related errors (which is this subject in a nutshell).
Writing generic code in C without using macros isn't the easiest thing to do.
For a (very) basic solution using a variadic macro:
#define CALL_AND_CHECK(f, r, ...) \
do { \
if (f(__VA_ARGS__) != r) \
{ \
fprintf(stderr, "program_name: " #f "() failed\n"); \
perror(#f "(): "); \
} \
} while (0)
(See Why are there sometimes meaningless do/while and if/else statements in C and C++ macros? for why the "meaningless" do/while loop is used)
Note that printing out an error message and not actually handling the error is almost certainly a bad idea. Generally, different errors need to be handled in different ways, so generic code like this may not be particularly useful. If you don't want to try and recover from any of these errors, you could exit(), which might be okay for an assignment, though in a real-world program you wouldn't want to do that.
Related
I expect I can do something like this:
int i = 0;
until (i == 2){
printf("yes\n");
i++;
}
Without telling detail about what until does, I'm sure reader know what is the algorithm from code above. Yes I know I can just use while(!condition){}.
The output will be:
yes
yes
So is it possible that I can achieve my goal?
I feel macro able to do this with define or something else. But I'm lack of knowledge about preprocessing directive syntax in C
#define until <what should I fill here>
Edit:
Many people triggered from what am I doing. I'm sorry for if I bother you guys. Don't worry, this syntax is just for my self only. So I hope I don't bother code reader who accidentally read my code or C priest.
First of all, and I can't stress this enough: making your own secret, private language using function-like macros is a cardinal sin in C. It is perhaps the worst thing you can ever do.
Why? Because other people reading your code are expected to know C. They are however not expected to know your secret private macro language. Furthermore, they have absolutely no interest in learning your secret private macro language.
So please never do things like this in real programs.
That being said, you pretty much already answered the question yourself:
#define until(condition) while(!(condition))
Note that condition, being a function-like macro parameter, should be placed inside a parenthesis. This prevents accidental operator precedence bugs. For example if the caller passes until(i + 1) then you want it to loop while(!(i+1)) and not while(!i + 1).
From Expert C Programming:
Macro use is best confined to naming literal constants,
shorthand for a few well-chosen constructs. Define the macro name all
in capitals so that, in use, it's instantly clear it's not a function
call. Shun any use of the C preprocessor that modifies the underlying
language so that it's no longer C.
Re: "I'm sure reader know what is the algorithm from code above."
No, it would confuse one even more as the keyword until is not part of the C language. It doesn't take much to type a few extra characters.
That being said, you could do:
#define until(condition) while(!(condition))
Compile your program with:
gcc -E -nostdinc main.c
to see what changes the preprocessor made.
But it would still be an abomination, and not something one would condone.
Using until is useful in select cases.
Sometimes an algorithm or software contract uses until in its definition, so it is good to see that match in code.
Yet re-writing language semantics adds confusion and maintenance costs.
Consider a comment when until is needed.
int i = 0;
// until (i == 2) {
while (i != 2) {
printf("yes\n");
i++;
}
Yes, you can use define for that. See the following example for the macro definition
#include <stdio.h>
#define until(x) while(!(x))
int main() {
int i = 0;
until (i == 2){
printf("iteration %d\n", i);
i++;
}
return 0;
}
If you run it, the output would be
iteration 0
iteration 1
I don't know why you would do this, until is a mostly abandoned keyword for a reason. But this should work:
#define until(cond) while (!(cond))
I'm writing a Scheme interpreter. For each built-in type (integer, character, string, etc) I want to have the read and print functions named consistently:
READ_ERROR Scheme_read_integer(FILE *in, Value *val);
READ_ERROR Scheme_read_character(FILE *in, Value *val);
I want to ensure consistency in the naming of these functions
#define SCHEME_READ(type_) Scheme_read_##type_
#define DEF_READER(type_, in_strm_, val_) READ_ERROR SCHEME_READ(type_)(FILE *in_strm_, Value *val_)
So that now, instead of the above, in code I can write
DEF_READER(integer, in, val)
{
// Code here ...
}
DEF_READER(character, in, val)
{
// Code here ...
}
and
if (SOME_ERROR != SCHEME_READ(integer)(stdin, my_value)) do_stuff(); // etc.
Now is this considered an unidiomatic use of the preprocessor? Am I shooting myself in the foot somewhere unknowingly? Should I instead just go ahead and use the explicit names of the functions?
If not are there examples in the wild of this sort of thing done well?
I've seen this done extensively in a project, and there's a severe danger of foot-shooting going on.
The problem happens when you try to maintain the code. Even though your macro-ized function definitions are all neat and tidy, under the covers you get function names like Scheme_read_integer. Where this can become an issue is when something like Scheme_read_integer appears on a crash stack. If someone does a search of the source pack for Scheme_read_integer, they won't find it. This can cause great pain and gnashing of teeth ;)
If you're the only developer, and the code base isn't that big, and you remember using this technique years down the road and/or it's well documented, you may not have an issue. In my case it was a very large code base, poorly documented, with none of the original developers around. The result was much tooth-gnashing.
I'd go out on a limb and suggest using a C++ template, but I'm guessing that's not an option since you specifically mentioned C.
Hope this helps.
I'm usually a big fan of macros, but you should probably consider inlined wrapper functions instead. They will add negligible runtime overhead and will appear in stack backtraces, etc., when you're debugging.
I'll start by saying it's a homework thing, but its got nothing to do with me learning C.
We are tasked to implement solutions to the Reader/Writer conflict using Semaphores and priority. Doing so in Java for the class.
The book we are working with, however uses C(I think) to handle their code examples. I'm not all that familiar with standard C and I can't figure out how to search existing literature for the answer I seek.
In the code:
semaphore x=1,wsem=1;
int readcount;
void reader()
{
While (true){
semWait(x);
readCount++;
if(readcount==1)
{
semWait(wsem);
}
semSignal(x);
READUNIT();
semWait(x);
readcount; /* <--- the questionable command */
if(readcount==0)
{
semSignal(wsem)
}
semSignal(x);
}
}
The line I have "starred" doesn't make any apparent sense. I appears to be simply stating or declaring the name of the variable. Is this some form of decrement I've never seen, or does this do something else? It seems like I'd be able to find it in some C-guide somewhere, but I haven't a clue what it's doing so I don't really know how to ASK what it's doing.
A variable name followed by a semicolon is a complete legal statement in C, but it does nothing. The form is rarely used, although it can be useful to suppress unused-variable warnings in some compilers.
From context, what it was probably supposed to be is readcount--;. That's the C decrement operator, undoing the readcount++ above.
Does your source also have the (erroneous) capital-W While and inconsistent spellings of readcount? If so, that's several bad typos in one short example and you should be suspicious of everything else in the book.
I have an assert macro that resolves to an if, something like this:
#define assert(expr) \
if (!(expr)) \
{ \
handle_failed_assert(); \
}
Ignore how handle_failed_assert() works, and you don't need to cite the do { ... } while(0) trick. Please, focus on the functionality behind this.
Now, the real question comes. Sometimes I want to force and assert, and make it meaningful. So we use this:
assert(!"Assert cause carefully described.");
The problem is that we have this compiler, vrxcc, based on RVCT 2.2, that throws this warning when compiling that:
#236-D: controlling expression is constant
Of course, that resolves to a compile constant if.
How could I trick the compiler into accepting that?
Your problem ultimately boils down to "my compiler is too smart, how do I make it stop complaining about something that, yes, is true and is often a programmer mistake, but in this case is not a programmer mistake". There are only two ways to do that:
Outwit the compiler. This is compiler-dependent.
Tell the compiler "don't complain, this is not a mistake." This is compiler-dependent.
I know nothing about vrxcc. R's comment goes towards doing the first. This sort of thing is almost guaranteed to work:
extern int __truefunc(void);
#define assert(expr) ((__truefunc() && (expr)) || __assert_fail(#expr))
where truefunc is a function that always returns 1, and that you can compile separately to outwit the compiler. The cost, of course, is that darned useless run-time call.
The "tell the compiler" method is nicer, but requires some sort of compiler documentation assist.
Addendum: it occurred to me in the shower that in your particular case, you've already decided to panic, so you could just have a panic function, and call that here. The disadvantage is that you have to change all your existing common_assert(!"some string") calls, but at least you can do that mechanically.
It might be nice if the language had a two-argument assert built in or as a standard thing. The FreeBSD kernel uses KASSERT for this these days, more or less as:
#define KASSERT(expr, panic_args) \
do { if (!(expr)) panic panic_args; } while (0)
which is a bit klunky syntactically, but is nicely flexible:
KASSERT(foo.field == FOO_MAGIC,
("memory overwrite of foo data structure: %d != %d",
foo.field, FOO_MAGIC));
Sometimes I have to write code that alternates between doing things and checking for error conditions (e.g., call a library function, check its return value, keep going). This often leads to long runs where the actual work is happening in the conditions of if statements, like
if(! (data = (big_struct *) malloc(sizeof(*data)))){
//report allocation error
} else if(init_big_struct(data)){
//handle initialization error
} else ...
How do you guys write this kind of code? I've checked a few style guides, but they seem more concerned with variable naming and whitespace.
Links to style guides welcome.
Edit: in case it's not clear, I'm dissatisfied with the legibility of this style and looking for something better.
Though it pains me to say it, this might be a case for the never-popular goto. Here's one link I found on on the subject: http://eli.thegreenplace.net/2009/04/27/using-goto-for-error-handling-in-c/
I usually write that code in this way:
data = (big_struct *) malloc(sizeof(*data));
if(!data){
//report allocation error
return ...;
}
err = init_big_struct(data);
if(err){
//handle initialization error
return ...;
}
...
In this way I avoid calling functions inside if and the debug is easier because you can check the return values.
Dont use assert in production code.
In debug mode, assert should never be used for something that can actually happen (like malloc returning NULL), rather it should be used in impossible cases (like array index is out of bounds in C)
Read this post for more.
One method which I used to great effect is the one used by W. Richard Stevens in Unix Network Programming (code is downloadable here. For common functions which he expects to succeed all the time, and has no recourse for a failure, he wraps them, using a capital letter (code compressed vertically):
void * Malloc(size_t size) {
void *ptr;
if ( (ptr = malloc(size)) == NULL)
err_sys("malloc error");
return(ptr);
}
err_sys here displays the error and then performs an exit(1). This way you can just call Malloc and know that it will error out if there is a problem.
UNP continues to be the only book I've where I think the author has code which checks the return values of all the functions which it's possible to fail. Every other book says "you should check the return values, but we'll leave that for you to do later".
I tend to
Delegate error checking to wrapper functions (like Stevens)
On error, simulate exceptions using longjmp. (I actually use Dave Hanson's C Interfaces and Implementations to simulate exceptions.)
Another option is to use Don Knuth's literate programming to manage the error-handling code, or some other kind of preprocessor. This option is available only if you get to set the rules for your shop :-)
The only grouping property of code like this is that there simply is an externally imposed sequence that it has to follow. This is why you put these allocations into one function, but this is a very weak commonality. Why some people recommend to abandon the scope advantages of nested if's is beyond my understanding. You are effectively trying to put lipstick on a pig (no insult intended) - the code's nature will never yield anything clean, the best you can do is to use the compilers help to catch (maintenance) errors. Stick with the if's IMHO.
PS: if I haven't convinced you yet: what will the goto-solution look like if you have to take ternary decisions? The if's will get uglier for sure, but the goto's???