K
Keith Thompson
Tobias Blass said:I wanted to do that first, but I think it's quite ugly to have a separate C file/* error.h */
#ifndef H_ERROR
#define H_ERROR
const char *const *const errstrs;
#endif
/* error.c */
#include "error.h"
static const char *const error_strings[] = {
"first error",
"second error"
};
const char *const *const errstrs = error_strings;
just for the table, so I wanted to ask whether it's possible to do that in the
header file instead.
I believe the answer to your question is no.
It's just one extra file; it shouldn't be that big a deal.
If you define the object in a header, then you have one instance
of the object for each translation unit (.c file) that includes the
header. If you have only one .c file for your program, you can get
away with it, but any sizeable program will have multiple .c files.
Generally, .h files are for declarations, and .c files are for
definitions. (I'm speaking rather loosely here; we've had long
arguments about the meaning of "definition" which I'd rather not
repeat.)
(The const thing is a good hint, I find it rather difficult to remember which
const has which effect */
The "cdecl" program is very handy for this kind of thing; I used
it to figure out how to declare error_strings above.
That's possibly true, but I think it's easier to change an entry in a table
than to change it in a function.
You're just changing an entry in a table either way. The function
can simply return an element of the table. It can also do bounds
checking, and perhaps return an empty string or a null pointer
for error_string(9999).
And the error.h file doesn't change when you add or change
error messages, so anything that depends on it doesn't have to be
recompiled; you can just recompile error.c and relink. (If you're
using reasonable build tools, this just means that rebuilding your
program will be a bit faster.)