home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.databases.ingres
- Path: sparky!uunet!zaphod.mps.ohio-state.edu!darwin.sura.net!uvaarpa!cv3.cv.nrao.edu!mail-to-news-gateway
- From: CS_PAUL@GSBVAX.UCHICAGO.EDU (Paul Ford 312/702-0335)
- Subject: RE: Linked List Problem
- Message-ID: <920812110140.20a00063@GSBVAX.UCHICAGO.EDU>
- Sender: root@nrao.edu (Operator)
- Organization: National Radio Astronomy Observatory
- Date: Wed, 12 Aug 1992 16:01:40 GMT
- Lines: 139
-
- Jeff Rule (11 Aug 92) writes:
-
- >I have a problem with the embedded SQL portion of INGRES. I want to fetch data
- >into a linked list. The declaration is normally something like:
- >
- >struct tag
- >{
- > char var1[20];
- > struct tag *next;
- >};
- >
- >But, when the precompiler gets through with this, it turns the *next into
- >*...FIELD ERROR. I've temporarily defined the next pointer to be void. I don't
- >get any errors, but don't know what the results will be. Any suggestions?
- >
- >Jeff Rule/Apple Computer rule@apple.com
-
- Are you really using the name 'next'? This is a reserved SQL keyword (see
- appendix A of the _INGRES/SQL Reference Manual_). That may be part of the
- problem.
-
- I just tried some sample code with INGRES 6.4/01 (vax.vms/02) under VMS 5.4-3
- and it compiled and ran without error. My declarations were as follows:
-
- exec sql BEGIN DECLARE SECTION ;
-
- struct aa
- {
- struct aa * nextitem ;
- char name[40] ;
- } ;
-
- typedef struct aa aa_t ;
-
- aa_t list[100] ;
- aa_t * list_head ;
- aa_t * listp ;
-
- exec sql END DECLARE SECTION ;
-
- If you still have problems (perhaps due to an earlier version of INGRES)
- you can try a refinement of your "void *" trick. Make two declarations, a
- real one for the C compiler and a fake one for the embedded preprocessor.
-
- /* Real declaration, seen only be the C compiler. */
- struct aa
- {
- struct aa * nextitem ;
- char name[40] ;
- } ;
-
-
- #if 1==0 /* Fake declaration, seen only by the esqlc preprocessor. */
-
- exec sql BEGIN DECLARE SECTION ;
- struct aa
- {
- void * nextitem ;
- char name[40] ;
- } ;
- exec sql END DECLARE SECTION ;
-
- #endif
-
- This works because the embedded preprocessor ignores #if/#endif C
- preprocessor statements and sees the fake struct declaration.
-
- One might wonder if there is a portability problem associated with the fact
- that sizeof(void *) can't be assumed to be the same as sizeof(struct aa*).
- I believe there isn't based on my understanding of how the embedded
- preprocessor generates C code.
-
- Esqlc does need to know the sizes of atomic types (long, short, float,
- double, char arrays, etc.) that it actually stuffs data into or reads data
- from during queries and form operations. But it doesn't try to compute
- structure member offsets, it just places the literal text of the member
- reference in the function calls it generates. It does need to know the
- size of the member, but it leaves the offset and address computation to the
- C compiler. As long as the real and fake declarations agree where their
- use overlaps (e.g., name is char[40] in both), everything should work
- fine.
-
- In fact, in the fake declaration, you can go one step further and remove
- the nextitem member altogether. This fake declaration for esqlc
- works as well as the one above:
-
- #if 1==0 /* Fake declaration, seen only by the esqlc preprocessor. */
-
- exec sql BEGIN DECLARE SECTION ;
- struct aa
- {
- /* struct aa * nextitem ; */
- char name[40] ;
- } ;
- exec sql END DECLARE SECTION ;
-
- #endif
-
-
- All of this is pretty ugly, and doesn't seem necessary under 6.4 in this
- particular case. However there is a situation where we use this fake
- declaration trick all the time -- to declare function arguments passed
- using ANSI C function prototypes. The advantages of ANSI C function
- prototypes far outweigh the inconvenience of ESQLC's inability to recognize
- them, and hence make this trick very worthwhile. Here's how we do it.
-
- /* Pre-ANSI C traditional function definition. ESQLC declarations fit
- right in. */
-
- char * sample_function(id, name)
- exec sql BEGIN DECLARE SECTION ;
- long id ;
- char * name ;
- exec sql END DECLARE SECTION ;
- {
- ...
- }
-
- /* ANSI C function definition using prototypes. ESQLC declarations
- require the fake declaration trick. */
-
- char * sample_function( long id, const char * name )
- #if 1==0 /* for esqlc */
- exec sql BEGIN DECLARE SECTION ;
- long id ;
- char * name ;
- exec sql END DECLARE SECTION ;
- #endif
- {
- ...
- }
-
- Paul Ford
- --------------------------------------------------------------------------
- GSB Computing Services 312.702.0335
- University of Chicago cs_paul@gsbvax.uchicago.edu
- 1101 E. 58th Street
- Chicago IL 60637
- --------------------------------------------------------------------------
-