Hi pete,
sorry for getting back to you only now (busy today, so answers
which require much thought take longer)
Michael said:
Hiho,
pete wrote:
[snip]
Having static c in the header file,
defeats the whole point of the static keyword.
Not necessarily. You can for example use a header for
testing/extended error state returns and so on and count
the number of errors encountered/store error states and
so on. In order to make sure that the translation units
or modules do not get confused, you use static variables.
I have seen similar mechanisms in large code.
I don't understand how that header file is used, and how there
would be a benefit from having a static object declaration in it.
As I said in the snipped part, I do not think it is a good
technique. I do no longer have access to the code but an
untested sample header file could look like that:
#ifndef CATCH_ERROR
#define CATCH_ERROR
#include <stddef.h> /* for size_t */
/* error states */
enum ce_errortypes {
CE_OK=0,
CE_INVALID_INPUT,
/* Easy checks ^ */
CE_START_BAD_ERRORS,
/* Bad Errors v */
CE_INVALID_OP,
CE_INVALID_RANGE,
CE_END
};
static unsigned long int ce_statecounters[(size_t)CE_END+1];
#ifdef COUNT_ERRORS
# define RETURN(ret_int) \
{ ce_statecounters[( (ret_int) >= 0 && (ret_int)< CE_END \
&& (int)(ret_int)==(ret_int) ) \
? (int)(ret_int) : CE_END] += 1; \
return (ret_int);}
#else
# define RETURN(ret_int) return (ret_int);
#endif
#define HOW_MANY_CHECK_ERRORS(num) {enum ce_errortypes counter;\
(num) = 0; for(counter=1;counter<CE_START_BAD_ERRORS;\
counter++) {(num) += ce_statecounters[counter];}}
#define HOW_MANY_BAD_ERRORS(num) {enum ce_errortypes counter;\
(num) = CE_START_BAD_ERRORS+1; for(counter=1;\
counter<CE_END;counter++)\
{(num) += ce_statecounters[counter];}}
#define HOW_MANY_STRANGE_ERRORS(num) (num) = ce_statecounters[CE_END]
#endif
It is right now only for (non-negative) int returns but I did
not bother wo write more tests and mapping and so on.
The functions return 0/CE_OK on success and you do
if (ret=fun1(....))
RETURN(..appropriate error value..);
You just include the header for the files you want to test and use
RETURN instead of return.
In your test routine or somewhere else you just find out
about the types of encountered errors by using HOW_MANY_..._ERRORS
It can come in handy for simulation software where you do not
necessarily have convergence in every step; so you just count the
"not converged" errors and decide based on that number whether
the result is acceptable or whether you suspect that the result
and the repercussions if wrong might get your customers to want
you to pay for the damage...
You make ce_statecounters static because you only want to count
it per file.
> What would a program that used it, be like?
Ugly. I think this is answered above.
> Which C files would include it, in a program?
Those which need this kind of treatment?
I am not trying to be evasive but I am not sure what you want to
know. In the example with the simulation software, typically
the high level solver routines and the matrix assembly would use
that kind of stuff.
> How many C files would there be in a program which used it.
42.
Honestly, are you kidding?
--Michael