[comp.sys.amiga.programmer] Is this valid C?

dave@csis.dit.csiro.au (David Campbell) (05/06/91)

Is this valid C?

Its just that this will compile on my favourite Unix compiler but won't
on Lattice V5.10.

I wish G++ was around for the Amiga!!!!!!

It turns out that C++ (on my Sparc) spits out similar code (I'm using
C++ on the sun to develop programs for the Amiga).

/*--------------------------------------------------------------------------*/
extern struct thing t;

struct thing {
	int n;
	char *s;
};

main()
{
	t.n = 10;
	t.s = "hello";
}
/*--------------------------------------------------------------------------*/

-- Dave Campbell
-- dave@csis.dit.csiro.au

-- 
dave campbell

zap@lysator.liu.se (Zap Andersson) (05/06/91)

dave@csis.dit.csiro.au (David Campbell) writes:

>Is this valid C?

>Its just that this will compile on my favourite Unix compiler but won't
>on Lattice V5.10.

>I wish G++ was around for the Amiga!!!!!!

>It turns out that C++ (on my Sparc) spits out similar code (I'm using
>C++ on the sun to develop programs for the Amiga).

>/*--------------------------------------------------------------------------*/
>extern struct thing t;

This is very invalid, since struct thing isn't defined yet. However the line
extern struct thing *t; 
is valid, even though 'thing' isn't defined yet.

>struct thing {
>	int n;
>	char *s;
>};


>main()
>{
>	t.n = 10;
>	t.s = "hello";
>}
>/*--------------------------------------------------------------------------*/

Question is how an access of the  t->n  and t->s would go, (if it
was defined as a pointer, in my case) now? I.e:
 
struct foop *p;

struct foop { int a; char *b };

main()
{
	p = malloc(...)
        p->a = 39;  /* Will complier barf here? Since the contents of
                       the structure 'foop' was defined AFTER the 'pointer
                       to unknown structure' p was created? Hmmmm? */
}

>-- Dave Campbell
>-- dave@csis.dit.csiro.au

>-- 
>dave campbell
--
* * * * * * * * * * * * * * * * *          (This rent for space)
* My signature is smaller than  * Be warned! The letter 'Z' is Copyright 1991
* yours!  - zap@lysator.liu.se  * by Zap Inc. So are the colors Red, Green and
* * * * * * * * * * * * * * * * * Greenish-yellow (Blue was taken by IBM) 

ken@cbmvax.commodore.com (Ken Farinsky - CATS) (05/06/91)

In article <1991May5.222328.16225@csis.dit.csiro.au> dave@csis.dit.csiro.au (David Campbell) writes:
>Is this valid C?
>
>Its just that this will compile on my favourite Unix compiler but won't
>on Lattice V5.10.
>
>/*----------(code removed)--------------------------------------------*/
>-- Dave Campbell -- dave@csis.dit.csiro.au

Try something like this, and make sure that you have "t" defined
in some other source file (you have it extern):

struct thing
    {
    int n;
    char *s;
    };

extern struct thing t;

main()
{
t.n = 10;
t.s = "hello";
}

Your problem was defining the structure after the reference.  Some compliers
may allow this, SAS does not seem to.
-- 
--
Ken Farinsky - CATS - (215) 431-9421 - Commodore Business Machines
uucp: ken@cbmvax.commodore.com   or  ...{uunet,rutgers}!cbmvax!ken
bix:  kfarinsky

davidm@uunet.UU.NET (David S. Masterson) (05/07/91)

>>>>> On 5 May 91 22:23:28 GMT, dave@csis.dit.csiro.au (David Campbell) said:

David> Its just that this will compile on my favourite Unix compiler but won't
David> on Lattice V5.10.

David> /*----------------------------------------------------------------*/
David> extern struct thing t;

David> struct thing {
David> 	int n;
David> 	char *s;
David> };

David> main()
David> {
David> 	t.n = 10;
David> 	t.s = "hello";
David> }
David> /*-----------------------------------------------------------------*/

Is there another file that has the definition of 't' in it?  If not, then this
shouldn't link (but it should compile) as there is no allocation of space for
't'.
--
====================================================================
David Masterson					Consilium, Inc.
(415) 691-6311					640 Clyde Ct.
uunet!cimshop!davidm				Mtn. View, CA  94043
====================================================================
"If someone thinks they know what I said, then I didn't say it!"

dltaylor@cns.SanDiego.NCR.COM (Dan Taylor) (05/07/91)

In <1991May5.222328.16225@csis.dit.csiro.au> dave@csis.dit.csiro.au (David Campbell) writes:

>Is this valid C?

Doesn't look right to me.  You have declared the struct (as extern) before
you have defined it (the description just below).

>extern struct thing t;

>struct thing {
>	int n;
>	char *s;
>};

Then you proceed to use a structure tag "t", in main(), that is either not
properly defined, or declared, depending on what the complier does with the
previous conflict.

Where does the compiler choke?

By the way, try running that through "lint".  It isn't perfect, but I've
found a few common typos, and more than a few definition/declaration
errors using it.

Dan Taylor

comeau@ditka.Chicago.COM (Greg Comeau) (05/10/91)

In article <616@lysator.liu.se> zap@lysator.liu.se (Zap Andersson) writes:
>struct foop *p;
>struct foop { int a; char *b };
>main() { p->a = 39;  /* Will complier barf here? */ }

There will be a no barf since at the ->a, foop is no longer an incomplete
type.  It is not a problem.

- Greg
-- 
	 Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418
                          Producers of Comeau C++ 2.1
          Here:attmail.com!csanta!comeau / BIX:comeau / CIS:72331,3421
                     Voice:718-945-0009 / Fax:718-441-2310

tricky@cix.compulink.co.uk (Richard Harrison) (05/10/91)

Subject: Re: Is this valid C?
Newsgroups: comp.sys.amiga.programmer
References: <1991May5.222328.16225@csis.dit.csiro.au>

From article <1991May5.222328.16225@csis.dit.csiro.au>, by dave@csis.dit.csiro.au (David -
Campbell):
> I wish G++ was around for the Amiga!!!!!!
Give me time, and it will be. I estimate somewhen in the summer. I've got the compiler
going, I'm just having *major* hassles with the standard C++ libraries.

/---------------------+---------------------------------------------------\
|     .           .   | Richard J. Harrison, tricky@cix.compulink.co.ukc  |
|   .__  (__  __)  .  |  '.co.ukc', the domain where international mail   |
|     /     ~~______  |             costs $0.06/kb                        |
|  __/    ^   \    /  +---------------------------------------------------+
| / /\ . /|  _ \  /   | Sometimes the above address fails, if so use      |
| \/  \|/ |_/\\_\/__/ | tricky%cix.compulink.co.uk@specialix.co.uk        |
\---------------------+---------------------------------------------------/

lawsonse@vttcf.cc.vt.edu (Shannon Lawson) (05/10/91)

> 
> In article <616@lysator.liu.se> zap@lysator.liu.se (Zap Andersson) writes:
> >struct foop *p;
> > >struct foop { int a; char *b };
> > >main() { p->a = 39;  /* Will complier barf here? */ }
> > 
> > There will be a no barf since at the ->a, foop is no longer an incomplete
> > type.  It is not a problem.
>          ^^^^^^^^^^^^^^^^^^^
 
I disagree.  p is a pointer to foop, and has not been allocated a foop to which
it may point.  Depending on the compiler, p points to some random location, so
you are happily sticking the value 39 into some nebulous area.  Although your
syntax is correct (and the compiler may not gag), you should see a problem
at runtime when you try to reference p.
 
ALWAYS make sure your pointers point to something valid!
 
> 
> - Greg
> -- 
> 	 Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418
>                           Producers of Comeau C++ 2.1
>           Here:attmail.com!csanta!comeau / BIX:comeau / CIS:72331,3421
>                      Voice:718-945-0009 / Fax:718-441-2310
 

-- 
  Shannon Lawson                    ||  Virginia Polytechnic Institute 
  Graduate Student                  ||     & State University 
  Harry Lynde Bradley Department of ||
  Electrical Engineering            ||  E-Mail:  lawsons@csgrad.cs.vt.edu
 
  Disclaimer:  If I put my foot in my mouth, I can hardly hold someone else
  responsible, now can I?

jdickson@jato.jpl.nasa.gov (Jeff Dickson) (05/11/91)

In article <38542@ditka.Chicago.COM> comeau@csanta.attmail.com (Greg Comeau) writes:
>In article <616@lysator.liu.se> zap@lysator.liu.se (Zap Andersson) writes:
>>struct foop *p;
>>struct foop { int a; char *b };
>>main() { p->a = 39;  /* Will complier barf here? */ }
>
>There will be a no barf since at the ->a, foop is no longer an incomplete
>type.  It is not a problem.
>
>- Greg
>-- 
>	 Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418
>                          Producers of Comeau C++ 2.1
>          Here:attmail.com!csanta!comeau / BIX:comeau / CIS:72331,3421
>                     Voice:718-945-0009 / Fax:718-441-2310

	Perhaps the compiler wouldn't barf, but the program would. 
"*p" is declared as a pointer to a structure of type "foop". Structure
"foop" is defined so the compiler would know at what offset each
member occurred at, but "*p" is not pointing to an allocated instance
of it. Now if you had:

		struct foop { int a; char *b } p;

	...then

		p.a = 39;

	...would be valid.


-jeff

dillon@overload.Berkeley.CA.US (Matthew Dillon) (05/11/91)

In article <38542@ditka.Chicago.COM> comeau@ditka.Chicago.COM (Greg Comeau) writes:
>In article <616@lysator.liu.se> zap@lysator.liu.se (Zap Andersson) writes:
>>struct foop *p;
>>struct foop { int a; char *b };
>>main() { p->a = 39;  /* Will complier barf here? */ }
>
>There will be a no barf since at the ->a, foop is no longer an incomplete
>type.	It is not a problem.
>
>- Greg

    That is, assuming 'p' is initialized to something valid :-)

    struct foop *p;
    struct foop { int a; char *b };
    struct foop xx;

    main()
    {
	p = &xx;
	p->a = 39; ...
    }

					-Matt

--

    Matthew Dillon	    dillon@Overload.Berkeley.CA.US
    891 Regal Rd.	    uunet.uu.net!overload!dillon
    Berkeley, Ca. 94708
    USA

comeau@ditka.Chicago.COM (Greg Comeau) (05/14/91)

In article <53200@nigel.ee.udel.edu> lawsonse@vttcf.cc.vt.edu (Shannon Lawson) writes:
>> In article <616@lysator.liu.se> zap@lysator.liu.se (Zap Andersson) writes:
>> >struct foop *p; struct foop { int a; char *b };
>> > >main() { p->a = 39;  /* Will complier barf here? */ }
>> > There will be a no barf since at the ->a, foop is no longer an incomplete
>> > type.  It is not a problem.
>I disagree.  p is a pointer to foop, and has not been allocated a foop to which
>it may point.  Depending on the compiler, p points to some random location, so
>you are happily sticking the value 39 into some nebulous area.  Although your
>syntax is correct (and the compiler may not gag), you should see a problem
>at runtime when you try to reference p.

Please do not compare apples to oranges.

The original posting dealt strictly wiht the accessibility  of p/a and
hence it was answered in that context.

Re the runtime issues (not the original compile time issues), what you 
describe is most certainly true given the way the code snipet above is
composed.

- Greg
-- 
	 Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418
                          Producers of Comeau C++ 2.1
          Here:attmail.com!csanta!comeau / BIX:comeau / CIS:72331,3421
                     Voice:718-945-0009 / Fax:718-441-2310

zap@lysator.liu.se (Zap Andersson) (05/16/91)

comeau@ditka.Chicago.COM (Greg Comeau) writes:

>In article <53200@nigel.ee.udel.edu> lawsonse@vttcf.cc.vt.edu (Shannon Lawson) writes:
>>> In article <616@lysator.liu.se> zap@lysator.liu.se (Zap Andersson) writes:
>>> >struct foop *p; struct foop { int a; char *b };
>>> > >main() { p->a = 39;  /* Will complier barf here? */ }
>>> > There will be a no barf since at the ->a, foop is no longer an incomplete
>>> > type.  It is not a problem.
>>I disagree.  p is a pointer to foop, and has not been allocated a foop to which
>>it may point.  Depending on the compiler, p points to some random location, so
>>you are happily sticking the value 39 into some nebulous area.  Although your
>>syntax is correct (and the compiler may not gag), you should see a problem
>>at runtime when you try to reference p.

>Please do not compare apples to oranges.

>The original posting dealt strictly wiht the accessibility  of p/a and
>hence it was answered in that context.

Yes, and I don't know how it got there since I wrote it - and I had TWO
pices of code in it. In ONE of them I explicitly wrote malloc(sizeof(foo))
just to SHOW people that that wasn't the point. I seem to have forgottn
that in the last example - sorry - but that was NOT the point at ALL, ok?

The point was: If you say:

struct kevlar_oysters *ipp; /* Wich is valid EVEN IF kevlar_oysters are un-
                               known as this time: ipp is a pointer to an
                               'unknown' structure */

and AFTER that you do:

struct kevlar_oysters { int foo; float bar; };

Now the structure TYPE itself is known - however, is a compiler
sufficiently intellegent to know that it's previously marked as 'pointer to
unknown structure' is suddenly a KNOWN structore? I dont know, I think it
is compiler dependant. So if I NOW do

ipp = calloc(39,sizeof(struct kevlar_oysters)); /* To keep you happy :-) */
if (ipp) /* To keep you EVEN HAPPIER B-] */
   ipp->bar = 39;

The POINT is, will the COMPILER barf here, period. I dont care if the
program kills memory - I won't RUN it, I will just use it as a nice
exercise for my compiler (up - and stretch - and down - and relax)

>Re the runtime issues (not the original compile time issues), what you 
>describe is most certainly true given the way the code snipet above is
>composed.

Agreement is utter and total. The code is never run - just compiled. Hep!

>- Greg
>-- 
>	 Comeau Computing, 91-34 120th Street, Richmond Hill, NY, 11418
>                          Producers of Comeau C++ 2.1
>          Here:attmail.com!csanta!comeau / BIX:comeau / CIS:72331,3421
>                     Voice:718-945-0009 / Fax:718-441-2310
--
* * * * * * * * * * * * * * * * *          (This rent for space)
* My signature is smaller than  * Be warned! The letter 'Z' is Copyright 1991
* yours!  - zap@lysator.liu.se  * by Zap Inc. So are the colors Red, Green and
* * * * * * * * * * * * * * * * * Greenish-yellow (Blue was taken by IBM) 

jdickson@jato.jpl.nasa.gov (Jeff Dickson) (05/17/91)

In article <635@lysator.liu.se> zap@lysator.liu.se (Zap Andersson) writes:
>comeau@ditka.Chicago.COM (Greg Comeau) writes:
>
>>In article <53200@nigel.ee.udel.edu> lawsonse@vttcf.cc.vt.edu (Shannon Lawson) writes:
>>>> In article <616@lysator.liu.se> zap@lysator.liu.se (Zap Andersson) writes:
>>>> >struct foop *p; struct foop { int a; char *b };
>>>> > >main() { p->a = 39;  /* Will complier barf here? */ }
>>>> > There will be a no barf since at the ->a, foop is no longer an incomplete
>>>> > type.  It is not a problem.
>>>I disagree.  p is a pointer to foop, and has not been allocated a foop to which
>>>it may point.  Depending on the compiler, p points to some random location, so
>>>you are happily sticking the value 39 into some nebulous area.  Although your
>>>syntax is correct (and the compiler may not gag), you should see a problem
>>>at runtime when you try to reference p.
>
>>Please do not compare apples to oranges.
>
>>The original posting dealt strictly wiht the accessibility  of p/a and
>>hence it was answered in that context.
>
>Yes, and I don't know how it got there since I wrote it - and I had TWO
>pices of code in it. In ONE of them I explicitly wrote malloc(sizeof(foo))
>just to SHOW people that that wasn't the point. I seem to have forgottn
>that in the last example - sorry - but that was NOT the point at ALL, ok?
>
>The point was: If you say:
>
>struct kevlar_oysters *ipp; /* Wich is valid EVEN IF kevlar_oysters are un-
>                               known as this time: ipp is a pointer to an
>                               'unknown' structure */
>
>and AFTER that you do:
>
>struct kevlar_oysters { int foo; float bar; };
>
>Now the structure TYPE itself is known - however, is a compiler
>sufficiently intellegent to know that it's previously marked as 'pointer to
>unknown structure' is suddenly a KNOWN structore? I dont know, I think it
>is compiler dependant. So if I NOW do
>
>ipp = calloc(39,sizeof(struct kevlar_oysters)); /* To keep you happy :-) */
>if (ipp) /* To keep you EVEN HAPPIER B-] */
>   ipp->bar = 39;
>
>The POINT is, will the COMPILER barf here, period. I dont care if the
>program kills memory - I won't RUN it, I will just use it as a nice
>exercise for my compiler (up - and stretch - and down - and relax)
>
	I always declare structures before I make reference to them. I imagine
that it depends on if your compiler allows forward references. 

	Now that this is out of the way, can we please move on? Can't believe
we're still haggling over this idotic topic!

rick@tmi.com (05/20/91)

In article <dillon.7597@overload.Berkeley.CA.US>, dillon@overload.Berkeley.CA.US (Matthew Dillon) writes:
>     That is, assuming 'p' is initialized to something valid :-)
> 
>     struct foop *p;
>     struct foop { int a; char *b };
>     struct foop xx;
> 
>     main()
>     {
> 	p = &xx;
> 	p->a = 39; ...
>     }
> 

And generally, it's nicer to declare the struct before declaring a pointer
to it.  The compiler doesn't care which goes first usually, but it's nicer
for the programmer to see:

    struct foop { int a; char *b };
    struct foop *p;
    struct foop xx;

Also, although your compiler may not care, you need a semicolon after the
declaration of the second member of struct foop:

    struct foop { int a; char *b; };
                                ^
-- 
.--------------------------------------------------------------------------.
|[- O] Rick Stevens                                                        |
|  ?   EMail: uunet!zardoz!tmiuv0!rick -or- uunet!zardoz!xyclone!sysop     |
|  V                (rick@tmi.com)              (sysop@ssssc.com)          |
|      CIS: 75006,1355 (75006.1355@compuserve.com from Internet)           |
|                                                                          |
|           "If it's stupid and it works, it ain't stupid!"                |
`--------------------------------------------------------------------------'