[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c

Keep coherent .h and .c

pozz

4/20/2011 10:13:00 PM

Many times I need to define a long list of variables in a C code and use
it in several other modules.

For example, I have a C file with constant strings used in the overall
program:
--- strings.c ---
const char msg1[] = "Please, wait";
const char msg2[] = "Enter the password";
const char msg3[] = "Password isn't correct";
...
---

Of course I need a corresponding include file:
--- strings.h ---
extern const char *msg1[];
extern const char *msg2[];
extern const char *msg3[];
---

I'm asking if there is a simple way to keep the two files coherent each
other. Indeed, after months of coding, I could delete some strings
and/or add some other strings in C file, without update the include file.

What about your opinion about the following method?
--- strings.def ---
#ifdef DEFINE_STRINGS
# define STRING(name, str) const char name[] = str
#endif
#ifdef DECLARE_STRINGS
# define STRING(name, str) extern const char *name
#endif
--- strings.c ---
#define DEFINE_STRINGS
#include "strings.def"
--- strings.h ---
#define DECLARE_STRINGS
#include "strings.def"
---

8 Answers

Ian Collins

4/20/2011 10:24:00 PM

0

On 04/21/11 10:12 AM, pozz wrote:
> Many times I need to define a long list of variables in a C code and use
> it in several other modules.
>
> For example, I have a C file with constant strings used in the overall
> program:
> --- strings.c ---
> const char msg1[] = "Please, wait";
> const char msg2[] = "Enter the password";
> const char msg3[] = "Password isn't correct";
> ...
> ---
>
> Of course I need a corresponding include file:
> --- strings.h ---
> extern const char *msg1[];
> extern const char *msg2[];
> extern const char *msg3[];
> ---
>
> I'm asking if there is a simple way to keep the two files coherent each
> other. Indeed, after months of coding, I could delete some strings
> and/or add some other strings in C file, without update the include file.

Code generate them from a common source.

--
Ian Collins

Ben Bacarisse

4/20/2011 10:59:00 PM

0

pozz <pozzugno@gmail.com> writes:
<snip>
> What about your opinion about the following method?
> --- strings.def ---
> #ifdef DEFINE_STRINGS
> # define STRING(name, str) const char name[] = str
> #endif
> #ifdef DECLARE_STRINGS
> # define STRING(name, str) extern const char *name
> #endif
> --- strings.c ---
> #define DEFINE_STRINGS
> #include "strings.def"
> --- strings.h ---
> #define DECLARE_STRINGS
> #include "strings.def"
> ---

Your types are wrong. The declaration and the definition should use the
same type.

--
Ben.

Keith Thompson

4/20/2011 11:19:00 PM

0

pozz <pozzugno@gmail.com> writes:
> Many times I need to define a long list of variables in a C code and use
> it in several other modules.
>
> For example, I have a C file with constant strings used in the overall
> program:
> --- strings.c ---
> const char msg1[] = "Please, wait";
> const char msg2[] = "Enter the password";
> const char msg3[] = "Password isn't correct";
> ...
> ---
>
> Of course I need a corresponding include file:
> --- strings.h ---
> extern const char *msg1[];
> extern const char *msg2[];
> extern const char *msg3[];
> ---

This is wrong. You define msg1 as an array of char, then declare it as
an array of pointers to char.

Note that either
extern const char *msg1;
or
extern const char msg1[];

If you want to make an array object visible in a .h file, you also need
to make its size visible, and therefore fixed -- but that defeats the
purpose of defining the content in a .c file.

Probably your best bet is:

--- strings.h ---
extern const char *msg1;

--- strings.c ---
const char *msg1 = "Please wait";

(and of course likewise for msg2 and msg3).

[...]

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.ne...
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

China Blue Veins

4/20/2011 11:28:00 PM

0

In article <ionlos$elt$1@nnrp.ngi.it>, pozz <pozzugno@gmail.com> wrote:

> Many times I need to define a long list of variables in a C code and use
> it in several other modules.
>
> For example, I have a C file with constant strings used in the overall
> program:
> --- strings.c ---
> const char msg1[] = "Please, wait";
> const char msg2[] = "Enter the password";
> const char msg3[] = "Password isn't correct";
> ...
> ---
>
> Of course I need a corresponding include file:
> --- strings.h ---
> extern const char *msg1[];
> extern const char *msg2[];
> extern const char *msg3[];
> ---

I use a macro processor so I can do
public char msg[] is {"Please, wait."}
and it puts in the .h
extern char msg[];
and it puts in the .c
char msg[] = "Please, wait.";

Or if I written
private char msg[] is {"Please, wait."}
and it puts in the .c
static char msg[];
...
static char msg[] = "Please, wait.";

With a bit of effort and m4 or another macro processor, you can let the computer
do your muck work for you.

You can filters like sed
s/<=/<=/g
s/>=/>=/g
...
and use all sorts of nifty Unicode characters in your program instead of just
ASCII.


http://www.yahoodrummers.com/davey/kliban/images/wyp_deeperme...

--
Damn the living - It's a lovely life. I'm whoever you want me to be.
Silver silverware - Where is the love? At least I can stay in character.
Oval swimming pool - Where is the love? Annoying Usenet one post at a time.
Damn the living - It's a lovely life. I am in the Nile.

Morris Keesan

4/21/2011 2:39:00 AM

0

On Wed, 20 Apr 2011 19:18:33 -0400, Keith Thompson <kst-u@mib.org> wrote:

> pozz <pozzugno@gmail.com> writes:
>> Many times I need to define a long list of variables in a C code and use
>> it in several other modules.
>>
>> For example, I have a C file with constant strings used in the overall
>> program:
>> --- strings.c ---
>> const char msg1[] = "Please, wait";
>> const char msg2[] = "Enter the password";
>> const char msg3[] = "Password isn't correct";
>> ...
>> ---
>>
>> Of course I need a corresponding include file:
>> --- strings.h ---
>> extern const char *msg1[];
>> extern const char *msg2[];
>> extern const char *msg3[];
>> ---
>
> This is wrong. You define msg1 as an array of char, then declare it as
> an array of pointers to char.
>
> Note that either
> extern const char *msg1;
> or
> extern const char msg1[];

There appears to be a the end of a sentence missing here, but it's
important to note here that "extern const char *msg1;" is totally
incompatible with the definition "const char msg1[] = "Please, wait";

> If you want to make an array object visible in a .h file, you also need
> to make its size visible, and therefore fixed -- but that defeats the
> purpose of defining the content in a .c file.

Well, no, you don't, and no, it doesn't. It's perfectly legal to
define msg1 as above:
const char msg1[] = "Please, wait";
in a .c file, and have an extern declaration in a .h file that says
extern const char msg1[];

as long as the code which only sees the extern declaration doesn't try
to apply the sizeof operator to msg1.


> Probably your best bet is:
>
> --- strings.h ---
> extern const char *msg1;
>
> --- strings.c ---
> const char *msg1 = "Please wait";

I respectfully disagree. One thing that I do consider important is to
#include "strings.h" in strings.c. This won't keep you from having
items declared in one file or another that are missing from the other,
but it will make sure that the compiler will catch the error if the
declarations in the two files are not compatible, e.g. if the definition
declares msg1 as an array while the extern declaration declares it as
a (char *).

--
Morris Keesan -- mkeesan@post.harvard.edu

Keith Thompson

4/21/2011 2:41:00 AM

0

"Morris Keesan" <mkeesan@post.harvard.edu> writes:
> On Wed, 20 Apr 2011 19:18:33 -0400, Keith Thompson <kst-u@mib.org> wrote:
>> pozz <pozzugno@gmail.com> writes:
>>> Many times I need to define a long list of variables in a C code and use
>>> it in several other modules.
>>>
>>> For example, I have a C file with constant strings used in the overall
>>> program:
>>> --- strings.c ---
>>> const char msg1[] = "Please, wait";
>>> const char msg2[] = "Enter the password";
>>> const char msg3[] = "Password isn't correct";
>>> ...
>>> ---
>>>
>>> Of course I need a corresponding include file:
>>> --- strings.h ---
>>> extern const char *msg1[];
>>> extern const char *msg2[];
>>> extern const char *msg3[];
>>> ---
>>
>> This is wrong. You define msg1 as an array of char, then declare it as
>> an array of pointers to char.
>>
>> Note that either
>> extern const char *msg1;
>> or
>> extern const char msg1[];
>
> There appears to be a the end of a sentence missing here, but it's
> important to note here that "extern const char *msg1;" is totally
> incompatible with the definition "const char msg1[] = "Please, wait";

Yes, editing error. I won't bother to say what I meant to write, since
it would have been wrong.

>> If you want to make an array object visible in a .h file, you also need
>> to make its size visible, and therefore fixed -- but that defeats the
>> purpose of defining the content in a .c file.
>
> Well, no, you don't, and no, it doesn't. It's perfectly legal to
> define msg1 as above:
> const char msg1[] = "Please, wait";
> in a .c file, and have an extern declaration in a .h file that says
> extern const char msg1[];
>
> as long as the code which only sees the extern declaration doesn't try
> to apply the sizeof operator to msg1.

You're right!

>> Probably your best bet is:
>>
>> --- strings.h ---
>> extern const char *msg1;
>>
>> --- strings.c ---
>> const char *msg1 = "Please wait";
>
> I respectfully disagree. One thing that I do consider important is to
> #include "strings.h" in strings.c. This won't keep you from having
> items declared in one file or another that are missing from the other,
> but it will make sure that the compiler will catch the error if the
> declarations in the two files are not compatible, e.g. if the definition
> declares msg1 as an array while the extern declaration declares it as
> a (char *).

In this case, you disagree with what I wrote, but not with what
I meant. I meant merely that those declarations should be in
strings.h and strings.c, respectively. I omitted the #include
"strings.h" in strings.c, as well as the include guards in strings.h.
Sorry for not making that clear.

--
Keith Thompson (The_Other_Keith) kst-u@mib.org <http://www.ghoti.ne...
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Peter Nilsson

4/21/2011 3:24:00 AM

0

pozz <pozzu...@gmail.com> wrote:
> Many times I need to define a long list of variables in a
> C code and use it in several other modules.
>
> For example, I have a C file with constant strings used in the
> overall program:
> --- strings.c ---
>    const char msg1[] = "Please, wait";
>    const char msg2[] = "Enter the password";
>    const char msg3[] = "Password isn't correct";
>    ...
> ---
>
> Of course I need a corresponding include file:
> --- strings.h ---
>    extern const char *msg1[];
>    extern const char *msg2[];
>    extern const char *msg3[];
> ---
>
> I'm asking if there is a simple way to keep the two files coherent
> each other. ...

/* message.h */

#define semi_colon ;

/* messages maintained in one spot */
#define messages(M,_) \
M( msg1, "This is message 1." ) _ \
M( msg2, "Here is the second message." ) _ \
M( msg3, "The answer is 42!" )

#define as_decl( label, str ) \
extern const char label[]

#define as_defn( label, str ) \
const char label[] = str

#define as_dump(label, str ) \
puts( label )

messages(as_decl, semi_colon);


/* message.c */

/* #incldue "message.h" */

messages(as_defn, semi_colon);


/* main.c */

#include <stdio.h>
/* #include "message.h" */

int main(void)
{
messages(as_dump, semi_colon);
printf("message1: %s\n", msg1);
return 0;
}

cf. <http://groups.google.com/group/comp.lang.c/browse_f...
41752094223d6448/5f48068b48edfe5c>
<http://groups.google.com/group/comp.lang.c/msg/99b71d7028...

--
Peter

Fred

4/21/2011 3:51:00 PM

0

On Apr 20, 3:12 pm, pozz <pozzu...@gmail.com> wrote:
> Many times I need to define a long list of variables in a C code and use
> it in several other modules.
>
> For example, I have a C file with constant strings used in the overall
> program:
> --- strings.c ---
>    const char msg1[] = "Please, wait";
>    const char msg2[] = "Enter the password";
>    const char msg3[] = "Password isn't correct";
>    ...
> ---
>
> Of course I need a corresponding include file:
> --- strings.h ---
>    extern const char *msg1[];
>    extern const char *msg2[];
>    extern const char *msg3[];
> ---
>
> I'm asking if there is a simple way to keep the two files coherent each
> other. Indeed, after months of coding, I could delete some strings
> and/or add some other strings in C file, without update the include file.
>
> What about your opinion about the following method?
> --- strings.def ---
> #ifdef DEFINE_STRINGS
> #  define STRING(name, str)  const char name[] = str
> #endif
> #ifdef DECLARE_STRINGS
> #  define STRING(name, str)  extern const char *name
> #endif
> --- strings.c ---
> #define DEFINE_STRINGS
> #include "strings.def"
> --- strings.h ---
> #define DECLARE_STRINGS
> #include "strings.def"
> ---

If they are all strings, you could just #define them
in the .h file and dispense with the .c file completely.

mystrings.h:

#define MSG1 "Please, wait"
#define MSG2 "Enter the password"
etc.

Then there is no chance for mismatches

--
Fred K