[comp.lang.c] static, const, struct woes

engstrom@SRC.Honeywell.COM (Eric Engstrom) (06/26/91)

I have several questions regarding the following code:

/* -------------------------------------------------- */
/* This code is outside any block, thus "static". */

typedef struct {
   long cid;
   long uid;
 } entity;

	entity 		User_self = {1, 2};		/* D-1 */
const 	entity 		Session_self = {3, 4};		/* D-2 */
	entity const	Function_self = {5, 6};		/* D-3 */

entity foo1 = User_self;				/* F-1 */
entity foo2 = {User_self.cid, User_self.uid};		/* F-2 */

entity foo3 = Session_self;				/* F-3 */
entity foo4 = {Session_self.cid, Session_self.uid};	/* F-4 */

entity foo5 = Function_self;				/* F-5 */
entity foo6 = {Function_self.cid, Function_self.uid};	/* F-6 */

/* -------------------------------------------------- */

Q1) What difference (if any) is there between the three lines marked D-1, D-2,
    and D-3?  All are acceptable to my compiler (gcc 1.39 - Sun Sparc).
    (I did look at K&R-2 and the FAQ, but there was not enough meat for my
    taste ;-)

Q2) Why, if either D-2 or D-3 are truly legal, do the lines F-3 to F-6 all
    fail to compile with the following error:
	"initializer for static variable is not constant"

    Now I realize that D-1-2-3 are variables whose values are not necessarily
    defined until run-time, but why should the lines F-1 to F-6 be any
    different?  I (the compiler) know the amount of memory to allocate in all
    cases, so why must the initial values be constant?

Q3) How must I change my definitions (if possible) to accommodate lines
    D-1-2-3 being located in different code files and having "extern"
    references from this file?

  Note that the Sun C compiler (OS 4.1.1) gave more, and more cryptic, errors,
  even complaining about the "const" portion of D-1-2-3.


Actually, you can replace my struct definition with simple "int" declarations
and the same errors occur.

Eric
+---------
Eric Engstrom, Honeywell SRC		   | The verb form of 'committee' 
Inter: engstrom@src.honeywell.com	   |  is 'commit', as in 
UUCP:  {umn-cs,ems,bthpyd}!srcsip!engstrom |  "the committe was committed
MAIL: 3660 Technology Drive, Mpls, MN      |  to the Anoka Mental Hospital."

ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (06/26/91)

In article <1991Jun25.170806.23639@src.honeywell.com>, engstrom@SRC.Honeywell.COM (Eric Engstrom) writes:
> /* This code is outside any block, thus "static". */

None of the things is declared 'static', so they are not so much "static"
as "extern".

>       entity       User_self     = {1, 2};  /* D-1 */
> const entity       Session_self  = {3, 4};  /* D-2 */
> 	entity const Function_self = {5, 6};  /* D-3 */

In these three declarations, the expressions inside the
<initializer-list>s are <constant-expression>s, as they must be at top level.

> entity foo1 = User_self;				/* F-1 */
> entity foo2 = {User_self.cid, User_self.uid};		/* F-2 */

But User_self, User_self.cid, User_self.uid are NOT <constant-expression>s.
What you are trying to do makes sense, and the language could have been
defined so that it would work, but it wasn't.  The initial values given
to top-level variables must be <constant-expression>s.

>     Now I realize that D-1-2-3 are variables whose values are not necessarily
>     defined until run-time, but why should the lines F-1 to F-6 be any
>     different?  I (the compiler) know the amount of memory to allocate in all
>     cases, so why must the initial values be constant?

What has the initial value to do with the amount of memory to allocate?
In most C implementations, the _way_ that top-level and static variables
are initialised is for the compiler and linker to work together so that
already in the object file the right values are in place.  Top level
initialisations do not generate executable code (in most implementations
of C; C++ is different).

>   Note that the Sun C compiler (OS 4.1.1) gave more, and more cryptic, errors,
>   even complaining about the "const" portion of D-1-2-3.

The 'const' keyword is part of ANSI C (copied from C++).  Sun's documentation
makes it clear that the C compiler that comes with that release of the
operating system is not and is not intended to be an ANSI C compiler.  It's
a "pre-ANSI" (or "Classic") C compiler.
	#if !__STDC__
	#define const
	#endif
will get the code through.
-- 
I agree with Jim Giles about many of the deficiencies of present UNIX.

worley@compass.com (Dale Worley) (06/26/91)

In article <1991Jun25.170806.23639@src.honeywell.com> engstrom@SRC.Honeywell.COM (Eric Engstrom) writes:
	   entity 		User_self = {1, 2};		/* D-1 */
   const 	entity 		Session_self = {3, 4};		/* D-2 */
	   entity const	Function_self = {5, 6};		/* D-3 */

   entity foo1 = User_self;				/* F-1 */
   entity foo2 = {User_self.cid, User_self.uid};		/* F-2 */

   entity foo3 = Session_self;				/* F-3 */
   entity foo4 = {Session_self.cid, Session_self.uid};	/* F-4 */

   entity foo5 = Function_self;				/* F-5 */
   entity foo6 = {Function_self.cid, Function_self.uid};	/* F-6 */

   What difference (if any) is there between the three lines marked D-1, D-2,
   and D-3?

D2 and D3 define constant objects, which you aren't allowed to assign to.

   Why, if either D-2 or D-3 are truly legal, do the lines F-3 to F-6 all
   fail to compile with the following error:
	   "initializer for static variable is not constant"

Because the values of the expressions "Session_self", etc. aren't
"constant expressions".  In particular, to figure out what the value
is, a fetch from memory would have to be done.  Of course, from the
code above, the compiler could figure out what the fetch would yield,
but most compilers aren't that clever, and ANSI C doesn't require them
to be.

     Note that the Sun C compiler (OS 4.1.1) gave more, and more
     cryptic, errors,
     even complaining about the "const" portion of D-1-2-3.

Probably because the Sun C compiler doesn't implement 'const', and
thus thinks that 'const' is an identifier that you're trying to
declare.

Dale Worley		Compass, Inc.			worley@compass.com
--
BYOB if you like, but please don't let yourself go farther than you
can return.  Believe me, you're going to need most of those internal
organs in the morning.

mcdaniel@adi.com (Tim McDaniel) (06/27/91)

So

   const int n = 100;
   float a[n];

isn't legal ANSI C?  Well, fooey.  That's one of my major uses of
#define constants, and one of those I'd like to get rid of.

--
  "Of course he has a knife; he always has a knife.  We all have knives.
  It's 1183 and we're barbarians." -- Eleanor of Aquitaine, "A Lion in Winter"
Tim McDaniel                 Applied Dynamics Int'l.; Ann Arbor, Michigan, USA
Internet: mcdaniel@adi.com                UUCP: {uunet,sharkey}!amara!mcdaniel