473,385 Members | 1,521 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,385 software developers and data experts.

Looking for opinions on a C technique

I'm looking for opinions on a C technique I, and others, have used
successfully in the past. While some people swear by, apparently
others swear at it.

Assume a part of a program too large to fit comfortably in a single
source file, call it a "module". Let's call it "module A".

Also assume for various reasons module A needs a private data store
with static storage duration, accessible from files in more than one
translation unit. For a number of reasons it is necessary to have the
stored objects directly accessible where they are needed, so accessor
functions are ruled out.

Which leaves objects with external linkage.

To about name conflicts, all of module A's objects have names starting
with "moda_". Since they are referenced by name in several source
files, they must be defined in one, and declared as external in the
others.

Possibility 1:

They are just defined in one source file and matching extern
declarations are added to the others.

The big downside of this the files getting out of sync as
modifications are made. Maybe caught by the linker, maybe undefined
behavior at run time.

Possibility 2:

They are declared in a header file, and defined in a separate source
file that contains nothing else but the definitions.

Easier to keep in sync, anyone modifying such an object changes the
header file, then copies and pastes it into the C file, finally does a
search and replace of "extern" with nothing in the C file.

Less chance of getting out of sync, but still possible.

Possibility 3, which is possibility 2 automated with a little help
from the preprocessor:

File moda_vars.h:

#ifndef MODA_VARS_H
#define MODA_VARS_H

#ifdef DEFINE_MODA_VARS
#define MODULE
#else
#define MODULE extern
#endif

MODULE int moda_x;
MODULE int moda_y;

/* etcetera */

#endif /* MODA_VARS_H */
<eof>

File moda_vars.c:

#define DEFINE_MODA_VARS
#include "moda_vars.h"
<eof>

Files moda_code_1.c, moda_code_2.c, etc...
#include "moda_vars.h"
/* no definition of DEFINE_MODA_VARS */

The major point of option 3 is that there is no way that the
definitions of the objects and the external declarations can ever get
out of sync. Assuming a typical (and off-topic) build tool that
handles dependencies, any change to the header file forces a fresh
build of all the source files, definer and users.

In the situations where I've used this technique there is generally no
need to provide other than the default 0 initialization of static
objects, although there are somewhat more elaborate macros that allow
initializer expressions to be visible to the compiler in the defining
file and invisible in those that see the extern declarations.

I am not asking for opinions on whether or not the use of such shared
objects is a good idea, although this being comp.lang.c I'm sure I'll
get some.

What I am interested in is opinions on using a technique like
possibility 3, or any experiences anyone might care to share with
using something like this.

--
Jack Klein
Home: http://JK-Technology.Com
FAQs for
comp.lang.c http://www.eskimo.com/~scs/C-faq/top.html
comp.lang.c++ http://www.parashift.com/c++-faq-lite/
alt.comp.lang.learn.c-c++ ftp://snurse-l.org/pub/acllc-c++/faq
Nov 13 '05 #1
3 2109
On Wed, 02 Jul 2003 07:56:13 GMT
Jack Klein <ja*******@spamcop.net> wrote:
I'm looking for opinions on a C technique I, and others, have used
successfully in the past. While some people swear by, apparently
others swear at it.

Assume a part of a program too large to fit comfortably in a single
source file, call it a "module". Let's call it "module A".

Also assume for various reasons module A needs a private data store
with static storage duration, accessible from files in more than one
translation unit. For a number of reasons it is necessary to have the
stored objects directly accessible where they are needed, so accessor
functions are ruled out.

Which leaves objects with external linkage.

To about name conflicts, all of module A's objects have names starting
with "moda_". Since they are referenced by name in several source
files, they must be defined in one, and declared as external in the
others.

Possibility 1:

They are just defined in one source file and matching extern
declarations are added to the others.

The big downside of this the files getting out of sync as
modifications are made. Maybe caught by the linker, maybe undefined
behavior at run time.
I would never do this.
Possibility 2:

They are declared in a header file, and defined in a separate source
file that contains nothing else but the definitions.

Easier to keep in sync, anyone modifying such an object changes the
header file, then copies and pastes it into the C file, finally does a
search and replace of "extern" with nothing in the C file.

Less chance of getting out of sync, but still possible.
If you include the header file in the file that defines the variables,
the compiler will tell you about type miss-matches and the linker will
tell you if a variable is used but not defined.
Possibility 3, which is possibility 2 automated with a little help
from the preprocessor:

File moda_vars.h:

#ifndef MODA_VARS_H
#define MODA_VARS_H

#ifdef DEFINE_MODA_VARS
#define MODULE
#else
#define MODULE extern
#endif

MODULE int moda_x;
MODULE int moda_y;

/* etcetera */

#endif /* MODA_VARS_H */
<eof>

File moda_vars.c:

#define DEFINE_MODA_VARS
#include "moda_vars.h"
<eof>

Files moda_code_1.c, moda_code_2.c, etc...
#include "moda_vars.h"
/* no definition of DEFINE_MODA_VARS */

The major point of option 3 is that there is no way that the
definitions of the objects and the external declarations can ever get
out of sync. Assuming a typical (and off-topic) build tool that
handles dependencies, any change to the header file forces a fresh
build of all the source files, definer and users.
Used (by the original author) on code I am maintaining. Of course, you
have to make sure DEFINE_MODA_VARS is only defined in out source file.
In the situations where I've used this technique there is generally no
need to provide other than the default 0 initialization of static
objects, although there are somewhat more elaborate macros that allow
initializer expressions to be visible to the compiler in the defining
file and invisible in those that see the extern declarations.

I am not asking for opinions on whether or not the use of such shared
objects is a good idea, although this being comp.lang.c I'm sure I'll
get some.

What I am interested in is opinions on using a technique like
possibility 3, or any experiences anyone might care to share with
using something like this.


Not done anything clever for non-0 initialisations, but option 3 has
worked for a long time on the project I'm now involved with and we have
not had any problems with it.

<OT>
You may also want to look at "partial linking" of the group of files
done such that only the variables you want to expose have external
linkage beyond the library. This is mainly useful if the library is to
be distributed as a binary and you don't trust the users of the library
not to mess with your internal state.
</OT>
--
Mark Gordon
Paid to be a Geek & a Senior Software Developer
Although my email address says spamtrap, it is real and I read it.
Nov 13 '05 #2
In <8m********************************@4ax.com> Jack Klein <ja*******@spamcop.net> writes:
Possibility 2:

They are declared in a header file, and defined in a separate source
file that contains nothing else but the definitions.

Easier to keep in sync, anyone modifying such an object changes the
header file, then copies and pastes it into the C file, finally does a
search and replace of "extern" with nothing in the C file.

Less chance of getting out of sync, but still possible.


Possibility 2 improved:

They are declared in a header file, and defined in a separate source
file that includes the header file and contains nothing else but the
definitions.

No chance of getting out of sync without compiler complaints.

It's the same basic rule that says that the implementation of strcpy()
should also include <string.h>.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Da*****@ifh.de
Nov 13 '05 #3
If I have a bunch of stuff that is both static and needed by a small
collection of files, I will usually store it in a struct. I think it makes
usage much more obvious.

E.g.

struct graphics_data {
struct location loc;
struct viewport wind;
struct palette pal;
....
} my_shared_graphics_data;

struct mapping_data {
enum transformation transform;
enum ellipse_of_reference ellipse;
double scale;
double phi;
double rho;
....
} my_shared_mapping_data;

something like that. It's not very often that I do something like that
because INEVITABLY[*] I need to multithread the program at some point and
then I'm really, really sorry I made static variables.
[*] reminds me of the public television child's program "Zoom" which had a
running skit called "Love of Chair."
--
C-FAQ: http://www.eskimo.com/~scs/C-faq/top.html
"The C-FAQ Book" ISBN 0-201-84519-9
C.A.P. FAQ: ftp://cap.connx.com/pub/Chess%20Anal...ject%20FAQ.htm

Nov 13 '05 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

2
by: Alex | last post by:
Subject: Looking for an XML (database-based) Query Reporting Tool/advice First off, let me apologize if this thread is somewhat off topic... PLEASE REPLY TO: xml@solex-bi.com I am looking...
16
by: Andy Dingley | last post by:
I've just had a call from these people, http://www.browsealoud.com offering to sell me their wares. Anyone have an opinion on it ? I'll post my own thoughts about 24 hours from now. I'm...
43
by: Davey | last post by:
I am planning on developing an application which will involve skills that I have very little experience of - therefore I would appreciate comments on my initial design thoughts. Overview on...
8
by: rviray | last post by:
I am just looking for opinions about this project that I am working on. Background: Windows Application built under Delphi. The application uses 4-5 (depending on drill down avenue) deep modal...
1
by: JJ | last post by:
Hi, I am working on a proj and was thinking of creating a Document object that would hold filepath and doc name. And in this Document obj. when page that is using it loads I would call a...
13
by: Miro | last post by:
Ok I have been slowely - and ever so slowely teaching myself VB.net Currently I have created an MDB file by code, and added fields to the MDB file by code. I like this solution because, ( im...
4
by: Bill K | last post by:
Hello All, I've finally written an asp app that is worthy of resale and would like to hear from you who have done the same. What is the best way to protect my application? I would like to stay...
4
by: crystalattice | last post by:
I've been working on a game for several months but now I'm thinking I may be going about it the wrong way. It's an online RPG designed to recreate a pen & paper session, kind of like the OpenRPG...
112
by: Prisoner at War | last post by:
Friends, your opinions and advice, please: I have a very simple JavaScript image-swap which works on my end but when uploaded to my host at http://buildit.sitesell.com/sunnyside.html does not...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
If we have dozens or hundreds of excel to import into the database, if we use the excel import function provided by database editors such as navicat, it will be extremely tedious and time-consuming...
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.