Anthony
Anthony

Reputation: 633

How is struct definition AFTER reference legal?

I've been going through the Minix 1.1 source and noticed that a struct type is being referenced before it has been defined or declared. For example, main.c contains the following includes :

#include "file.h"
#include "fproc.h"
#include "glo.h"
#include "inode.h"
#include "param.h"
#include "super.h"

file.h contains the following :

EXTERN struct filp {
  mask_bits filp_mode;      /* RW bits, telling how file is opened */
  int filp_count;       /* how many file descriptors share this slot? */
  struct inode *filp_ino;   /* pointer to the inode */
  file_pos filp_pos;        /* file position */
} filp[NR_FILPS];

inode.h contains the following :

EXTERN struct inode {
  unshort i_mode;       /* file type, protection, etc. */
  uid i_uid;            /* user id of the file's owner */
  file_pos i_size;      /* current file size in bytes */
  real_time i_modtime;      /* when was file data last changed */
  gid i_gid;            /* group number */
  links i_nlinks;       /* how many links to this file */
  zone_nr i_zone[NR_ZONE_NUMS]; /* zone numbers for direct, ind, and dbl ind */

  /* The following items are not present on the disk. */
  dev_nr i_dev;         /* which device is the inode on */
  inode_nr i_num;       /* inode number on its (minor) device */
  short int i_count;        /* # times inode used; 0 means slot is free */
  char i_dirt;          /* CLEAN or DIRTY */
  char i_pipe;          /* set to I_PIPE if pipe */
  char i_mount;         /* this bit is set if file mounted on */
  char i_seek;          /* set on LSEEK, cleared on READ/WRITE */
} inode[NR_INODES];

Notice that struct filp contains a member filp_ino which is a pointer to type inode; however, type inode is not defined until later.

I was under the assumption that you either need to forward declare the type or define it before usage but obviously I'm wrong. Can someone point me in the right direction in understanding 1) why this is legal and 2) how the compiler is able to parse struct filp without advance knowledge of the inode type.

Upvotes: 1

Views: 72

Answers (1)

Jonathan Leffler
Jonathan Leffler

Reputation: 753695

You can create pointers to incomplete types (such as structure or union types) without knowing the size of the type, so you can use:

struct anything *p;

before you define the internals of struct anything (where anything is spelled inode in your example code). You can't dereference an incomplete type, but you can create pointers to it. If you don't need to access the internals of the incomplete type, you can pass the pointers around without ever defining the internals. This can help you create opaque types in C.

Upvotes: 1

Related Questions