Morris Keesan
4/9/2011 4:05:00 AM
On Fri, 08 Apr 2011 20:18:03 -0400, Keith Thompson <kst-u@mib.org> wrote:
> Ian Collins <ian-news@hotmail.com> writes:
>> On 04/ 9/11 10:43 AM, Tobias Blass wrote:
>>> Hi,
>>> I'm currently implementing a string lookup table, mapping error
>>> numbers to
>>> human readable strings. So my question is: Can I put the strings in a
>>> header
>>> file, or will I end up with N exact copies of this array (N being the
>>> number
>>> of inclusions of this file).
>>
>> There will only be one copy.
>
> The code in question is:
>
> /* error.h */
> #ifndef ERROR_H
> #define ERROR_H
>
> const char *errstrs[]={
> "first error",
> "second error",
> ...
> };
> #endif
>
> There won't be one copy per inclusion, because of the header guards,
> but you don't want a *definition* in a header file. If the header
> is included in two or more translation units that are linked into
> a single program, you might get multiple copies of the strings,
> or you might just get a link error. (I'm not quite sure what the
> language permits or requires here, but don't do it.)
>
> Here's what I came up with. Note that it makes errstrs a pointer
> rather than an array, but you can still refer to errstrs[0],
> errstrs[1], etc. If you make it an array, it means that client code
> can figure out how many elements there are, but it also means that
> you have to specify the length in the declaration and recompile if
> it changes.
>
> Note that identifiers starting with 'E' are reserved, so I changed
> the include guard macro name.
>
> /* 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;
This seems overly complex. Is there any good reason not to have
/* error.c */
const char *const error_strings[] = { "first error", "second error" };
/* error.h */
extern const char *const error_strings[];
I.e. why not just make error_strings a global array, and expose the
array name as an extern? Why go to the trouble of declaring a separate
pointer?
(Or, as was suggested elsewhere in this thread, make the whole thing
static, and provide a function to access the members of the array).
--
Morris Keesan -- mkeesan@post.harvard.edu