[Pdx-pm] off-topic: C90 declaration question

Austin Schutz tex at off.org
Mon Apr 17 18:31:29 PDT 2006


On Sun, Apr 16, 2006 at 09:00:33AM -0700, Marvin Humphrey wrote:
> 
>      int
>      meaning_of_life() {
>          have_fun();      /* "code" */
>          int i;           /* declare a variable, after "code" */
>          i = 42;
>          return i;
>      }
> 
> ... and you pass the "-pedantic" flag to the gcc compiler so that it  
> warns about non-C90-compliant code, you get this warning:
> 
>      meaning.c: In function 'meaning_of_life':
>      meaning.c:23: warning: ISO C90 forbids mixed declarations and code
> 
> That example is perfectly legal under the later C99 standard, but it  
> doesn't fly under C90 and there are a lot of compilers out there that  
> choke on it.
> 
> I understand that by imposing this constraint the creators of C were  
> trying to make life easy for compiler writers.  In my head, I imagine  
> an op-tree that has all the variable allocation routines up front.   
> "We'll tell the compiler about all the variables we might possibly  
> need in this block before we do anything with any of them."

	Not only are they making it easier for compiler writers, they're
making it easier for the poor sap stuck with code maintainance- it helps
to limit the number of places they have to look for variable declarations.

	When a function is called the return location is pushed on the stack.
Directly after this is the space used for lexically scoped variables. Normally
when you declare something like:

void myfunc() {
  int a,b;
}

	a is *(initial stack pointer)
	b is *(initial stack pointer + sizeof(int))

	the stack pointer is then changed to point directly past the
allocations. When the function returns the stack pointer is moved back to
the original location, where the return location is popped off the stack
and the cpu goes on its merry way.
	It's probably possible to perform this same task in the middle of
a function rather than at the beginning, though I would suspect the compiler
probably doesn't, for example:

void myfunc(int a) {
  if(a) {
    int b = 5;
  }
  int c = 4;
  return;
}

	the compiler can't know the relative location of c at compile time,
thus breaking the *(sp + sizeof(int)) assertion.
	I'm sure there's a clever workaround, but I would bet most compilers
probably just act as if all the declarations are at the beginning even if
they aren't.

	Someone smarter than me will probably correct any fallacious statements
herein.
	
	Austin



More information about the Pdx-pm-list mailing list