[comp.lang.c] Forward referrence of static variables.

davel@cai.uucp (David W. Lauderback) (01/02/91)

I think there is no "clean" solution to the problem I have but I wanted to test
my ability to post on the net so here is the problem:

I have some structures that make up a doublely linked list that I wish to
initialize.  The problem is I can't have two structures linked to each other.

Example:
--------------------
struct ll
{
        struct ll       *prev;  /* link to previous element */
        struct ll       *next;  /* link to next element */
        /* more fields ... */
};

/* Location 1 */

static struct ll	first = { 0,      &last /* , more data */ };
static struct ll	last  = { &first, 0     /* , more data */ };
--------------------

My solution is to add "extern struct ll last;" at location 1 and remove the
static's.  But I would much prefer to leave them static.  So back to the
original question, is there a way to forward referrence static variables?

I can think of two other unacceptable solutions.  One is to initialize these
in the code segment but this is harder to support and uses valuable space in my
particular application.  Another is that compilers will let you extern a
variable and then make it static, with a warning message.  However, this is not
portable so I can't use it.

					Thank in advance,
					David W. Lauderback
					uunet!cai!davel

PS. Please respond even if you don't have a comment.  I am trying to see how
    far this message gets.  I used distribution usa.  Should I have used a
    narrower distribution for this type of question?  Like ca maybe?

-- 
 -----------------------------------------------------------------------------
|     ###       #      ###      | David W. Lauderback (a.k.a. uunet!cai!davel)|
|    #   #     # #      #       |                                             |
|    #        #   #     #       |   (this space temporarily left blank)       |

ckp@grebyn.com (Checkpoint Technologies) (01/03/91)

In article <1991Jan2.084213.19442@cai.uucp> davel@cai.UUCP (David W. Lauderback) writes:
>I think there is no "clean" solution to the problem I have but I wanted to test
>my ability to post on the net so here is the problem:

In fact, I may have an appropriate solution.

>I have some structures that make up a doublely linked list that I wish to
>initialize.  The problem is I can't have two structures linked to each other.
> [example deleted]

Try this:

struct some_thing
   {
   struct some_thing *next, *prev;
   /* ... other members */
   };

struct some_thing things[] = {
   { &things[1], NULL, },
   { &things[2], &things[0], },
   { &things[3], &things[1], },

...and so on.  You get the idea.  This won't work if you have different
structure types to resolve this way; or else you could make a union of
them, though only ANSI specifies union initialization I understand.

You could make #defines for the individual array members if you want to
avoid referring to them as things[n].
-- 
First comes the logo: C H E C K P O I N T  T E C H N O L O G I E S      / /  
                                                                    \\ / /    
Then, the disclaimer:  All expressed opinions are, indeed, opinions. \  / o
Now for the witty part:    I'm pink, therefore, I'm spam!             \/

brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (01/03/91)

In article <24413@grebyn.com> ckp@grebyn.UUCP (Checkpoint Technologies) writes:
> In article <1991Jan2.084213.19442@cai.uucp> davel@cai.UUCP (David W. Lauderback) writes:
> >I think there is no "clean" solution to the problem
> In fact, I may have an appropriate solution.

Here is a clean solution. A few compilers may not implement it with full
efficiency, and it has the usual syntactic problems of macros, but it
does the trick.

If you want to do something like this:

  static struct ll	first = { 0,      &last /* , more data */ };
  static struct mm	last  = { &first, 0     /* , more data */ };

then do this:

  static struct { struct ll first; struct mm last; }
    shmoe = {      { 0,              &(shmoe.last)  /*, more data */ }
	    ,      { &(shmoe.first), 0              /*, more data */ }
	    } ;
  #define first (shmoe.first)
  #define last (shmoe.last)

Third time I've posted this since late September. I'd say it's FAQ time.

> This won't work if you have different
> structure types to resolve this way;

This one will.

---Dan