471,066 Members | 1,481 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

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

accessing static variables from outside their function

Does anyone know of a way of accessing and modifying variables declared
static within a function from outside that function? Please no
homilies on why it's bad practice: the context is very particular and
involves automatically generated code. I know several other ways of
attacking my problem, but this would be the cleanest if it could be made
to work.

A little more context. I use C as the output of a code generating
system which can, and frequently does, output very many functions that have a
consistent set of declarations, including variable names, at the top.
One of these is typically a static integer, call it "done", which causes
an immediate return if it has been set to 1, otherwise the function
proceeds. I take it that this is a well-known, trivial and banal piece
of code for permitting a function to run just once.

Now, however, circumstances have arisen where it might be desirable to
be able to reset this flag from outside the function in which it is
declared. Compiling, as I do, using gcc with -rdynamic, I am routinely
able, using dlopen and dlsym, to find the address of a function by name.
I had (naively) imagined that dladdr() would allow me to get the addresses
of symbols declared static within functions, but as I understand it
dladdr() only accesses global symbols. So what I am looking for is a
method for finding the address of a static integer variable called
"done" declared within "function001", as opposed to all other static
integer variables called "done" declared within all the many other
similar functions, in such a way that I can change its value - so
just getting a copy won't do.

I am asking in this group rather than in a gcc specific place because in
principle this is not a gcc-specific issue and my software compiles
using other compilers with comparable tricks. The more generic and
surgical a solution the better. But my functions may have a variable and
unpredictable number of arguments.

Pointers, RTFMs with page references and philosophical musings all
welcome. But an illustrative code fragment would be perfect.

--
Steve Blinkhorn <st***@prd.co.uk>
May 10 '06 #1
12 11230
Steve Blinkhorn said:
Does anyone know of a way of accessing and modifying variables declared
static within a function from outside that function?


Eeeeewwww. :-)

One obvious way - you could hack up a file scope pointer, and initialise it
first time in, to point at the static object.
int *flagptr;

void foo(void) /* I'm guessing your interface is written in stone! */
{
static int flag = 0; /* this is the bunny */

if(flagptr == NULL)
{
flagptr = &flag;
}

/* whatever floats your boat... */

return;
}

/* a different source file */

extern int *flagptr;

void bar(void)
{
foo();
*flagptr = 1; /* hack, chop, maim */
foo();
}
--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
May 10 '06 #2
Steve Blinkhorn wrote:
Does anyone know of a way of accessing and modifying variables declared
static within a function from outside that function?
...
A little more context. I use C as the output of a code generating
system which can, and frequently does, output very many functions that have a
consistent set of declarations, including variable names, at the top.
One of these is typically a static integer, call it "done", which causes
an immediate return if it has been set to 1, otherwise the function
proceeds. I take it that this is a well-known, trivial and banal piece
of code for permitting a function to run just once.

Now, however, circumstances have arisen where it might be desirable to
be able to reset this flag from outside the function in which it is
declared.

I am asking in this group rather than in a gcc specific place because in
principle this is not a gcc-specific issue and my software compiles
using other compilers with comparable tricks. The more generic and
surgical a solution the better. But my functions may have a variable and
unpredictable number of arguments.

Pointers, RTFMs with page references and philosophical musings all
welcome. But an illustrative code fragment would be perfect.


Two ideas:

(a) (Compiler specific) Check the sources of a debugger that works
with your toolchain, to see how to map a variable name into its run
time address.

(b) Change the problem definition. Write a filter (awk, perl, etc.) to
convert this:

(file xxx.c)

... yyy(...)
{
static int done;
/* the rest goes here */
}

into this:

int xxx_yyy_done;

... yyy(...)
{
/* the rest goes here */
}

(b and 1/2) Modify the "code generating system" to directly produce
form (b)

May 10 '06 #3
In article <12*************@corp.supernews.com>,
Steve Blinkhorn <st***@newsole.prd.co.uk> wrote:
Does anyone know of a way of accessing and modifying variables declared
static within a function from outside that function? Now, however, circumstances have arisen where it might be desirable to
be able to reset this flag from outside the function in which it is
declared. Compiling, as I do, using gcc with -rdynamic, I am routinely
able, using dlopen and dlsym, to find the address of a function by name. I am asking in this group rather than in a gcc specific place because in
principle this is not a gcc-specific issue and my software compiles
using other compilers with comparable tricks.


No, in principle it *is* gcc-specific -- or at least OS specific,
if the OS dictates that all executables must use the same debugger
table format.

On some systems, gcc emits debugging table entries that are
in executable sections not known to the OS-supplied debugger (and hence
are ignored by the system debugger.)

There is no requirement in the C standard that a symbol table of any
sort must be kept, beyond that which is implied by the discussions
of "external linkage" (which does not imply that a "linker" must
exist: it would be valid for a compiler to require that all sources
be named on the same command line, and for the compiler to do everything
in-memory.)

Anything further than "different executable formats may exist" is
not considered to be on topic for comp.lang.c
--
"law -- it's a commodity"
-- Andrew Ryan (The Globe and Mail, 2005/11/26)
May 10 '06 #4
Richard Heathfield <in*****@invalid.invalid> wrote:
: Steve Blinkhorn said:

: > Does anyone know of a way of accessing and modifying variables declared
: > static within a function from outside that function?

: Eeeeewwww. :-)

Absolutely, I do so agree ;-)

: One obvious way - you could hack up a file scope pointer, and initialise it
: first time in, to point at the static object.
Thanks for the amazingly fast response, but I don't think this one is a
runner, unless I misunderstand. Let me explain a little more. My
people write scripts that get translated into C. Their scripting may
generate (potentially) hundreds of functions (they don't actually
understand that that is what happens), though they do know that they
have generated a name for an object. So they need to reference their
object by its name to tell it to respond again. Imagine a function
called retrigger(objectname) as the natural thing to do. If I
understand you correctly, you are suggesting that for each function we
generate a variable in the global namespace that allows us to access the
static flag inside the function?

I'm sure this would actually work in that it would achieve the
objective, but it would involve a naming scheme for the global variables,
which might involve more trouble than some of the other methods I have
considered (which might require doing something with the function
interface).

This one is a bit like having a hole in your tooth, sort of exquisitely
unpleasant, isn't it?

--
Steve Blinkhorn <st***@prd.co.uk>
May 10 '06 #5
try Lisp or Scheme.

these languages are first class and functions can be returned and
stored.

C is 2nd class language.

May 10 '06 #6
In article <11**********************@i39g2000cwa.googlegroups .com>,
dick <di***********@hotmail.com> wrote:
try Lisp or Scheme. these languages are first class and functions can be returned and
stored. C is 2nd class language.


Could you give a formal definition by which we can objectively
decide whether a given programming language is "first class",
"2nd class", or some other class?

Languages themselves are seldom given class numbers. "first class"
is used in computer science to refer to *types of objects*,
not to the languages themselves. As phrased in a paper on DBPL:
http://www.sts.tu-harburg.de/papers/198x/MaSc89.pdf

Values of all DBPL types are first class language objects: They
can be named, denoted by expressions, stored in (persistent) variables
and passed as value and variable parameters.

In the C language, functions are not first class language objects
in that functions cannot be stored, dynamically created, nor passed
(only function -pointers-). That doesn't mean that the C -language-
itself is not first class.
Furthermore, languages in which functions can be returned and stored
do not necessarily allow examination or manipulation of the internal
details and values of the functions.
For an example of the complexities involved:

The Maple programming language (Maplesoft) allows procedures to
be created, stored, and passed. The names of parameters and local
variables and explicitly-declared global variables used by the
procedures may be examined, and the values stored in its
"remember" table may be examined and manipulated. There is no
simple way to examine the code of the procedure (there are
multilevel complex ways), but a new procedure can be easily produced
by "substituting" something for a name that one happens to know
appears inside the procedure (e.g., one could change a call to
sin into one to cos). Maple procedures may be "closures" -- they
can use local variables from the scope they were defined in
[even after that defining procedure has exitted], and the names
of those symbols can be examined and their values manipulated.
BUT -- when one is doing the "substitution" operation, Maple does
not notice that one is attempting to bind a enclosure variable
from the current scope into a part of the procedure that did not
originally use an enclosure variable. There are subtle cheats that
one can use to accomplish this if the procedure originally had
at least one enclosure variable reference to start with, but not
if the procedure did not originally have any enclosure references at all.

So is Maple a "first class language" or not? Where does the ability to
inject brand new enclosure information fit into your decision as exactly
what class a language is? If Maple is not "first class" because it
doesn't allow this subtle feature, and yet allows functions to be
stored and passed, and you have defined C to be 2nd class when it
doesn't allow functions to be manipulated in any of those ways, then
where does Maple sit? Is it a "One and six thirty-sevenths class language" ?
--
Programming is what happens while you're busy making other plans.
May 10 '06 #7
Steve Blinkhorn wrote:
Richard Heathfield <in*****@invalid.invalid> wrote:
int *flagptr; I'm sure this would actually work in that it would achieve the
objective,
but it would involve a naming scheme for the global variables,
which might involve more trouble than some of the other methods I have
considered (which might require doing something with the function
interface).

"done" declared within "function001"


int *flagptr001;

--
pete
May 10 '06 #8
Steve Blinkhorn schrieb:
Does anyone know of a way of accessing and modifying variables declared
static within a function from outside that function? Please no
homilies on why it's bad practice: the context is very particular and
involves automatically generated code. I know several other ways of
attacking my problem, but this would be the cleanest if it could be made
to work.


As you know it is not advisable, here is a method which may help.

enum {
E_STATE_FOO,
....
E_STATE_QUUUUUUUUUUUUUUUUUX,
E_NUM_STATES
};
int *gimmeStatus (unsigned int index)
{
static int status_table[E_NUM_STATES];
static int scratch;

if (index < E_NUM_STATES)
return &status_table[index];
else {
/* Do some error handling if necessary or insert
** assert(0);
** for your debug mode or whatever...
*/
return &scratch;
}
}

void example (int seventeen, int four) {
static int *pState = 0;

if (!pState) {
pState = gimmeStatus(E_STATE_FORTY_TWO);
*pState = MY_EXAMPLE_START_STATUS;
}

....
}

void externModification (void)
{
*gimmeStatus(E_STATE_FORTY_TWO) = 42;
}
Cheers
Michael
--
E-Mail: Mine is an /at/ gmx /dot/ de address.
May 10 '06 #9
Steve Blinkhorn wrote:

Does anyone know of a way of accessing and modifying variables
declared static within a function from outside that function?
Please no homilies on why it's bad practice: the context is very
particular and involves automatically generated code. I know
several other ways of attacking my problem, but this would be
the cleanest if it could be made to work.


int *foo(int param) {

static int foostate;

....
return &foostate;
} /* foo */

.....

int *p

...
do {
....
while (somethingelse) {
p = foo(...);
...
}
if (restart) *p = 0;
} while (!restart);

Now write your own homilies here and swear not to do it again.

--
"If you want to post a followup via groups.google.com, don't use
the broken "Reply" link at the bottom of the article. Click on
"show options" at the top of the article, then click on the
"Reply" at the bottom of the article headers." - Keith Thompson
More details at: <http://cfaj.freeshell.org/google/>
Also see <http://www.safalra.com/special/googlegroupsreply/>
May 11 '06 #10
Steve Blinkhorn said:
If I
understand you correctly, you are suggesting that for each function we
generate a variable in the global namespace that allows us to access the
static flag inside the function?
Well, if you have a brazillion of them, and each is a simple on/off flag,
how about a bit array for the flags? Hack your code generator so that the
internal static object initialises itself from the bit array, and writes
its state to the bit array at the end? (Indeed, this way you could do
without the static object altogether! Just use the bit array directly.)
This would avoid polluting the namespace with loads of silly names. The
only problem would be calculating the offset, but you could probably do
this easily enough with some kind of simple hashing scheme.
I'm sure this would actually work in that it would achieve the
objective, but it would involve a naming scheme for the global variables,
which might involve more trouble than some of the other methods I have
considered (which might require doing something with the function
interface).
If you can change the function interface, this becomes trivial, surely?
This one is a bit like having a hole in your tooth, sort of exquisitely
unpleasant, isn't it?


Er, I must admit I would not have chosen the word "exquisitely" in that
context. :-)

--
Richard Heathfield
"Usenet is a strange place" - dmr 29/7/1999
http://www.cpax.org.uk
email: rjh at above domain (but drop the www, obviously)
May 11 '06 #11
On Wed, 10 May 2006 17:30:26 -0000,
Steve Blinkhorn <st***@newsole.prd.co.uk> wrote
in Msg. <12*************@corp.supernews.com>
Thanks for the amazingly fast response, but I don't think this one is a
runner, unless I misunderstand. Let me explain a little more. My
people write scripts that get translated into C.
by an automated process (a C code generator), I'd assume.
If I
understand you correctly, you are suggesting that for each function we
generate a variable in the global namespace that allows us to access the
static flag inside the function?
As much as that would be a no-no in actual C programming, I'd say it's
fine within generated code. Make sure all those global flags are
declared static though.
I'm sure this would actually work in that it would achieve the
objective, but it would involve a naming scheme for the global variables,
Again, in generated code I see no problem with hideously chattily or
obscurely named identifiers.
which might involve more trouble than some of the other methods I have
considered (which might require doing something with the function
interface).
Another possibility.
This one is a bit like having a hole in your tooth, sort of exquisitely
unpleasant, isn't it?


No. I love code generators.

robert
May 11 '06 #12
Thanks guys for your thoughts, even those I had already had. You've
given me a good flavour for what might be possible.

--
Steve Blinkhorn <st***@prd.co.uk>
May 11 '06 #13

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

3 posts views Thread by Leigh Riley | last post: by
6 posts views Thread by pembed2003 | last post: by
2 posts views Thread by katekukku | last post: by
3 posts views Thread by Datta Patil | last post: by
12 posts views Thread by codefixer | last post: by
18 posts views Thread by Jack | last post: by
2 posts views Thread by Licheng Fang | last post: by
reply views Thread by leo001 | last post: by

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.