By using this site, you agree to our updated Privacy Policy and our Terms of Use. Manage your Cookies Settings.
446,206 Members | 1,028 Online
Bytes IT Community
+ Ask a Question
Need help? Post your question and get tips & solutions from a community of 446,206 IT Pros & Developers. It's quick & easy.

Local scope, external linkage?

P: n/a
I would like to share a variable between two functions defined in two
separate source files; no other functions will need the global variable
so I'd prefer to not give it file scope. Thus, I want a variable with
local scope, external linkage, and static storage.

I believe I can do this for the file that does not define the variable
by declaring it inside a function. Can I also avoid giving it file
scope in the file that does define the variable?

/* File 1 */

void function1(void) {
/* How do I make myGlobal have static storage,
* and external linkage?
*/
int myGlobal;
}

/* File 2 */

void function2(void) {
/* This does what I think it does, right? */
extern int myGlobal;
}

Thanks for your help,
-Peter
Nov 14 '05 #1
Share this Question
Share on Google+
4 Replies


P: n/a
Peter Ammon wrote:
I would like to share a variable between two functions defined in two
separate source files; no other functions will need the global variable
so I'd prefer to not give it file scope. Thus, I want a variable with
local scope, external linkage, and static storage.


You can't have one, I'm afraid.

If an identifier declared with external linkage is used in an
expression (other than as part of the operand of a sizeof operator
whose result is an integer constant), somewhere in the entire program
there shall be exactly one external definition for the identifier;
[C99 6.9]

External definitions always appear at file scope:

An external definition is an external declaration that is also a
definition of a function (other than an inline definition) or an
object.

translation-unit:
external-declaration
translation-unit external-declaration

About the closest you can get to what you want, I think, is to define
the variable in its own source file (or as the last declaration in one
of the source files in which it is used), and have block-scope
"extern" declarations (as in your example of function2()) in both the
functions that use the variable; this effectively limits scope to the
regions where the identifier is used. Since the same variable is
referenced in two separate translation units, the linkage must be the
maximum possible (i.e. "external").

Jeremy.
Nov 14 '05 #2

P: n/a
Peter Ammon wrote:
I would like to share a variable between two functions defined in two
separate source files; no other functions will need the global variable
so I'd prefer to not give it file scope. Thus, I want a variable with
local scope, external linkage, and static storage.

I believe I can do this for the file that does not define the variable
by declaring it inside a function. Can I also avoid giving it file
scope in the file that does define the variable?

/* File 1 */

void function1(void) {
/* How do I make myGlobal have static storage,
* and external linkage?
*/
int myGlobal;
}

/* File 2 */

void function2(void) {
/* This does what I think it does, right? */
extern int myGlobal;
}


C's linkage scheme is not fancy enough to do what
you desire. All identifiers with external linkage are
(potentially) visible to all parts of the program, and
there's no notion of a "package-private" linkage.

In the code you've shown, the identifier `myGlobal'
refers to two different objects:

- In function1(), it refers to an `auto' variable.
The identifier has no linkage, neither external
nor internal. You could change the storage class
by adding the `static' or `register' (or even
`typedef'!) keyword, but it wouldn't alter the
fact that this `myGlobal' has nothing at all to
do with any other `myGlobal' identifier that might
be lying around in your program.

- In function2(), `myGlobal' has external linkage.
When the various translation units are combined
into a program, this `myGlobal' and any others
that also have external linkage will be made to
refer to one object. Exactly one translation unit
must provide an actual definition of the object,
at file scope and without the `static' keyword --
and if that definition is a function or is a data
object that isn't `int', you've got trouble.

"You can't always get what you want." -- J&R

--
Er*********@sun.com

Nov 14 '05 #3

P: n/a
Peter Ammon wrote:

I would like to share a variable between two functions defined in two
separate source files; no other functions will need the global variable
so I'd prefer to not give it file scope. Thus, I want a variable with
local scope, external linkage, and static storage.

I believe I can do this for the file that does not define the variable
by declaring it inside a function. Can I also avoid giving it file
scope in the file that does define the variable?


I think the closest you can come is:

/* File1.h */
typedef /* whatever */ foo;
foo *fooptrgetter(void);

/* File1.c */
#include "File1.h"
static foo foovalue;
foo *fooptrgetter(void) {return &foovalue)

and now any other file can access it by #include "File1.h" and
getting the pointer as needed.

If foo is a struct you can ensure readonly access by coding the
foogetter() function. Modifying foo would then be restricted to
functions in File1.c, and you can control their use by prototyping
them in a separate header file. An example of this mechanism
exposes the statistics from my hashlib package (see download
section of my site).

--
Chuck F (cb********@yahoo.com) (cb********@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!

Nov 14 '05 #4

P: n/a
"CBFalconer" <cb********@yahoo.com> wrote in message
news:40***************@yahoo.com...
Peter Ammon wrote:
I would like to share a variable between two functions defined in two
separate source files; no other functions will need the global variable
[snip] I think the closest you can come is:

/* File1.h */
typedef /* whatever */ foo;
foo *fooptrgetter(void);

/* File1.c */
#include "File1.h"
static foo foovalue;
foo *fooptrgetter(void) {return &foovalue)

and now any other file can access it by #include "File1.h" and
getting the pointer as needed.

If foo is a struct you can ensure readonly access by coding the
foogetter() function.


Indeed, this scheme is largely pointless unless you do precisely that,
otherwise you might as well have the obvious:

/* File1.h */
typedef /* whatever */ foo;
extern foo foovalue;

/* File1.c */
#include "File1.h"
foo foovalue;

The only effective difference between this and the above is substituting one
external identifier for another.

Alex
Nov 14 '05 #5

This discussion thread is closed

Replies have been disabled for this discussion.