Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Best Way to Define/Declare/Initialize Variables Simultaneously?

Reply
Thread Tools

Best Way to Define/Declare/Initialize Variables Simultaneously?

 
 
David T. Ashley
Guest
Posts: n/a
 
      12-03-2004
Hi,

In my project, I typically declare and define variables in the .H
file, i.e.

DECMOD_MAIN UINT8 can_message_201_status_global
#ifdef MODULE_MAIN
= HAS_NEVER_BEEN_RECEIVED
#endif
;

where DECMOD_MAIN expands to nothing when compiling MAIN.C and expands
to "extern" when compiling other modules.

Is there a neater and more compact way to handle the initializers
(which appear in the definition but not in the declaration)? The
above (in the MAIN.H file) works, but it is inelegant. What are
others doing?

Again the goal is to define, declare, and initialize variables all in
the same place (to avoid having to keep consistency between the .C and
..H files).

Thanks, Dave.
 
Reply With Quote
 
 
 
 
Eric Sosman
Guest
Posts: n/a
 
      12-03-2004
David T. Ashley wrote:
> Hi,
>
> In my project, I typically declare and define variables in the .H
> file, i.e.
>
> DECMOD_MAIN UINT8 can_message_201_status_global
> #ifdef MODULE_MAIN
> = HAS_NEVER_BEEN_RECEIVED
> #endif
> ;
>
> where DECMOD_MAIN expands to nothing when compiling MAIN.C and expands
> to "extern" when compiling other modules.
>
> Is there a neater and more compact way to handle the initializers
> (which appear in the definition but not in the declaration)? The
> above (in the MAIN.H file) works, but it is inelegant. What are
> others doing?
>
> Again the goal is to define, declare, and initialize variables all in
> the same place (to avoid having to keep consistency between the .C and
> .H files).


The scheme you're using (or variants of it) is one way.

Another is to use a "helper" program to generate both
the .c and .h file from a single common source, which can
be written in a "little language" designed for the purpose.

HOWEVER, neither method will save you much work. Or to
put it differently, neither method *ought* to save you much
work, because the number of global variables should usually
be rather small. Using a global variable to pass information
between modules is admittedly convenient, but its convenience
is also its drawback: you lose all ability to control or
monitor the passage of the information. Some people like to
say that global variables "increase the coupling" between
modules, thus making them less modular, more interdependent,
and more interrelated in ways that are hard to analyze and
understand. If you've got a lot of global variables lying
around, you may be better off thinking of ways to get rid of
some of them than of ways to make it easier to add more.

--
http://www.velocityreviews.com/forums/(E-Mail Removed)

 
Reply With Quote
 
 
 
 
Mark A. Odell
Guest
Posts: n/a
 
      12-03-2004
(E-Mail Removed) (David T. Ashley) wrote in
news:(E-Mail Removed) om:

> Hi,
>
> In my project, I typically declare and define variables in the .H
> file, i.e.
>
> DECMOD_MAIN UINT8 can_message_201_status_global
> #ifdef MODULE_MAIN
> = HAS_NEVER_BEEN_RECEIVED
> #endif
> ;
>
> where DECMOD_MAIN expands to nothing when compiling MAIN.C and expands
> to "extern" when compiling other modules.
>
> Is there a neater and more compact way to handle the initializers
> (which appear in the definition but not in the declaration)? The
> above (in the MAIN.H file) works, but it is inelegant. What are
> others doing?


This is a poor hack, IMHO. Here's how I do it if I absolutely must expose
the variables themselves, e.g. if an accessor function is too much
overhead:

/* board.h - declaration only
*/
extern void *pBrdRamBaseAddr;
extern size_t brdRamSize;


/* board_product_1.c - definition
*/
void *pBrdRamBaseAddr = 0xFFF00100;
size_t brdRamBaseAddr = 0x00010000;


/* board_product_2.c - definition
*/
void *pBrdRamBaseAddr = 0xEEE00100;
size_t brdRamBaseAddr = 0x00020000;


/* board_product_3.c - definition
*/
void *pBrdRamBaseAddr = 0xDDD00100;
size_t brdRamBaseAddr = 0x00030000;


Now suppose I have foo.c and bar.c that do work with RAM in a generic
fashion on all three products. Foo.c and bar.c need only include board.h,
we'll let the makefile and linker do the magic.

product1.exe:
compile foo.c bar.c board_product_1.c
link foo.o bar.o board_product_1.o into product1.exe

product2.exe:
compile foo.c bar.c board_product_2.c
link foo.o bar.o board_product_2.o into product2.exe

product3.exe:
compile foo.c bar.c board_product_3.c
link foo.o bar.o board_product_3.o into product3.exe

all: product1.exe product2.exe product3.exe

Now when the RAM size in product2.exe changes to 0x00040000 I change it in
one place, board_product_2.c, and rebuild. Only one file gets
recompiled and only one exe gets relinked. If I had done this your way you
would have to recompile foo.c 3 times for each product, bar.c 3 times for
each product, and you would have had a single board.c file that would need
to get recompiled 3 times. Then 3 relinks. All this because only one value
changed that had no compile time impact on any source file except the
board file for product 2.

> Again the goal is to define, declare, and initialize variables all in
> the same place (to avoid having to keep consistency between the .C and
> .H files).


This does not make any sense. H files tell you type and names of variables
and the C file tells you the value of the variable.

--
- Mark ->
--
 
Reply With Quote
 
David T. Ashley
Guest
Posts: n/a
 
      12-04-2004
"Eric Sosman" <(E-Mail Removed)> wrote in message
news:coqf0k$ai9$(E-Mail Removed)...
> Another is to use a "helper" program to generate both
> the .c and .h file from a single common source, which can
> be written in a "little language" designed for the purpose.
>
> HOWEVER, neither method will save you much work. Or to
> put it differently, neither method *ought* to save you much
> work, because the number of global variables should usually
> be rather small. Using a global variable to pass information
> between modules is admittedly convenient, but its convenience
> is also its drawback: you lose all ability to control or
> monitor the passage of the information. Some people like to
> say that global variables "increase the coupling" between
> modules, thus making them less modular, more interdependent,
> and more interrelated in ways that are hard to analyze and
> understand. If you've got a lot of global variables lying
> around, you may be better off thinking of ways to get rid of
> some of them than of ways to make it easier to add more.


Eric,

In my own defense ...

I'm well familiar with the arguments against global variables. Essentially,
they lead to unrestrained connectivity, ill-defined interfaces, and a state
space which is too large (and is not shed as the program returns up the
calling tree). No argument from me on that one.

However, embedded work is done with processors that have a weak instruction
set (and don't support stack frames well), as well as small ROM sizes (about
30K). Programming the "right" way leads to ROM bloat. Global variables is
THE preferred interface technique. There is no other way. The customer
expects certain functionality, and it has to fit in the cheapest
microcontroller.

That being said ... what one is striving for is a minimal basis set (no
redundancy of information). So, generating the .C and .H from the same
script or input file makes sense. I've had good luck with Tcl/Tk.

Best regards, Dave.



 
Reply With Quote
 
Tim Rentsch
Guest
Posts: n/a
 
      12-04-2004
Eric Sosman <(E-Mail Removed)> writes:

> David T. Ashley wrote:
> > Hi,
> >
> > In my project, I typically declare and define variables in the .H
> > file, i.e.
> >
> > DECMOD_MAIN UINT8 can_message_201_status_global
> > #ifdef MODULE_MAIN
> > = HAS_NEVER_BEEN_RECEIVED
> > #endif
> > ;
> >
> > where DECMOD_MAIN expands to nothing when compiling MAIN.C and expands
> > to "extern" when compiling other modules.
> >
> > Is there a neater and more compact way to handle the initializers
> > (which appear in the definition but not in the declaration)? The
> > above (in the MAIN.H file) works, but it is inelegant. What are
> > others doing?
> >
> > Again the goal is to define, declare, and initialize variables all in
> > the same place (to avoid having to keep consistency between the .C and
> > .H files).

>
> The scheme you're using (or variants of it) is one way.
>
> Another is to use a "helper" program to generate both
> the .c and .h file from a single common source, which can
> be written in a "little language" designed for the purpose.


A refinement of this approach that in my experience works better is to
have the definition be actual source code, for example in a .c file,
and derive the declaration from it as a portion of a generated header
file. This way if there are any warnings or errors on the variable
definition, standard tools will take you right to the actual source
to be corrected. The case of the errors/warnings appearing on the
declaration still need further investigation, of course.


> HOWEVER, neither method will save you much work. Or to
> put it differently, neither method *ought* to save you much
> work, because the number of global variables should usually
> be rather small. Using a global variable to pass information
> between modules is admittedly convenient, but its convenience
> is also its drawback: you lose all ability to control or
> monitor the passage of the information. Some people like to
> say that global variables "increase the coupling" between
> modules, thus making them less modular, more interdependent,
> and more interrelated in ways that are hard to analyze and
> understand. If you've got a lot of global variables lying
> around, you may be better off thinking of ways to get rid of
> some of them than of ways to make it easier to add more.


Interesting story - a few years ago I implemented a lightweight
development environment that automatically generates function
prototypes for all functions. At the time I made conscious decision
(minor, but conscious) not to process variable definitions in a
similar way, pretty much for the reasons given in the above paragraph.
Later, for other reasons, I ended up adding the automatic generation
for variable declarations, and to my surprise it ended up helping a
lot even though the number of global variables was much smaller than
the number of functions. So even when good practices are followed and
the number of global variables is small, using software tools to
synchronize their declarations with the definitions yields a tangible
benefit.

 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      12-05-2004
Tim Rentsch wrote:
>

.... snip ...
>
> Interesting story - a few years ago I implemented a lightweight
> development environment that automatically generates function
> prototypes for all functions. At the time I made conscious


I would normally consider that a mistake. I certainly don't want
prototypes for all my functions - I prefer to have their complete
definition form their own prototypes, which simply means declare
before use. At the same time I can mark most functions as being
static, and not clutter up the link system nor force a maintainer
to check myriad files for usage. Similarly for any file scope
variables.

"static" is not used nearly as often as it should in C.

--
Chuck F ((E-Mail Removed)) ((E-Mail Removed))
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!


 
Reply With Quote
 
Tim Rentsch
Guest
Posts: n/a
 
      12-05-2004
CBFalconer <(E-Mail Removed)> writes:

> Tim Rentsch wrote:
> >

> ... snip ...
> >
> > Interesting story - a few years ago I implemented a lightweight
> > development environment that automatically generates function
> > prototypes for all functions. At the time I made conscious

>
> I would normally consider that a mistake. I certainly don't want
> prototypes for all my functions - I prefer to have their complete
> definition form their own prototypes, which simply means declare
> before use. At the same time I can mark most functions as being
> static, and not clutter up the link system nor force a maintainer
> to check myriad files for usage. Similarly for any file scope
> variables.
>
> "static" is not used nearly as often as it should in C.


Sorry, apparently I implied something that isn't so.

The development environment allows and recognizes static functions,
and differentiates static function prototypes and non-static function
prototypes. Prototypes for static functions are available only in the
compilation of the file where those functions are defined. Only
public functions have their prototypes make it into a public
interface (header) file, where they are available to be #include'd
by other compilation units. (The mechanism for variables is similar
although different in details.)

On the topic of using function order so most function definitions also
serve the purpose of prototypes - certainly that's something that's
common in C code, and indeed something I used to do myself before
having automatic prototype generation in the development environment.
I can only report that the experience of developers using the DE has
been that having automatic prototype generation for all functions is
extremely helpful, and the freedom to place functions without having
to worry about order dependencies has turned out to be much more of a
boon than was expected.

Compilations done using the DE normally include all the following
compilation flags (among others):

-Wimplicit-function-declaration
-Wstrict-prototypes
-Wmissing-prototypes
-Wmissing-declarations
-Wredundant-decls
-Werror

As you would expect, having these flags turned on all the time gets
rid of certain kinds of program errors and helps carry out various
program restructurings (or refactorings, to use the currently popular
term). The completely automatic generation of prototypes for all
functions allows this mode to be used with essentially no "mindless
editing" overhead.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Put variables into member variables or function variables? tjumail@gmail.com C++ 9 03-23-2008 04:03 PM
best way to initialize variables from constructor 34stunts@gmail.com Java 1 09-17-2006 10:58 AM
best way to transfer variables from 1 page to a 2nd to a 3rd page nicholas ASP .Net 5 04-21-2005 01:43 PM
Best Way to Define/Declare/Initialize Variables Simultaneously? David T. Ashley C++ 6 12-05-2004 09:37 AM
Re: Best way to implement ASP Session variables Steve C. Orr, MCSD ASP .Net 0 07-16-2003 09:09 PM



Advertisments