473,399 Members | 3,888 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,399 software developers and data experts.

Local scope, external linkage?

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
4 2716
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
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
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
"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 thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

3
by: j0mbolar | last post by:
void myfunction(void) { extern int myvariable; return ; } what is the point in allowing local variables to have external linkage? its scope is only myfunction so it can't be used anywhere...
5
by: pembed2003 | last post by:
Hi all, I am reading the book "C How to Program" and in the chapter where it discuss scope rule, it says there are four scopes for a variable: function scope file scope block scope...
8
by: TTroy | last post by:
I have a few questions about "scope" and "visibility," which seem like two different things. To me "visibility" of the name of a function or object is the actual code that can use it in an...
7
by: Kobu | last post by:
The code below isn't compiling for me (error message: conflicting types for 'total' - pointing to the extern declaration). Why wouldn't this work, since the types are different, the extern...
3
by: fctk | last post by:
are the following rules correct in C89/C90? ---- SCOPE RULES 1) the scope of an identifier declared inside a block is the block in which it is declared; 2) when you have nested blocks...
7
by: Christian Christmann | last post by:
Hi, I've a a question on the specifier extern. Code example: void func( void ) { extern int e; //...
2
by: Martijn van Buul | last post by:
Hi, Today, I stumbled over the following: I had a struct, whose scope only made sense within a single function, and I wanted to use std::swap() on it, like the following example: #include...
3
by: parag_paul | last post by:
hi All for the following #include <stdio.h> typedef struct{ int a ; int b; char* j; } AST;
1
by: Giacomo Catenazzi | last post by:
Hello, To learn the details of C, I've build the following example, could you check if it is correct and if it miss some important cases? Are there some useful (real cases) examples of: -...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
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
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...
0
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing,...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new...

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.