CSC447

Concepts of Programming Languages

Scope

Instructor: James Riely

Scope

  • Scope of an identifier
    • region of text in which it may be used

Common Scope Rules

  • z is in scope after its declaration until end of if

void f (int x) {
  int y = x + 1;
  if (x > y) {
    int z = y + 1;
    printf ("z = %d\n", z);
  }
}
          

Terminology: Occurrences

  • Occurrences of identifiers classified as one of
    • free occurrence has no matching binding
      
      y = 5*x;   // Free occurrences of x and y
                        
    • binding occurrence declares the identifier
      
      int y;    // binding occurrence of y
                        
    • bound occurrence follows matching declaration
      
      int y;    // Binding occurrence of y
      int x;    // Binding occurrence of x
      
      x=6;      // Bound occurrence of x
      y = 5*x;  // Bound occurrences of x and y
                        

Terminology: Occurrences

  • Complete programs usually have no free occurrences of identifiers
  • How do IDEs treat free occurrences?

Not Just Variables

  • Applies to identifiers for
    • normal variables
    • function parameters
    • function type parameters
    • function/method names
    • class names
    • and more

Forward Declarations

  • C, C++ require forward declarations
  • Most other modern languages do not

char f (int x);

char g (int x) {
  return f (x) + f (x);
}

char f (int x) {
  if (x > 0) { 
    return g (x >> 8);
  } else {
    return 1;
  }
}
          

Shadowing - Java


public class C {
  static void f () {
    int x = 1;
    {
      int y = x + 1;
      {
        int x = y + 1;
        System.out.println ("x = " + x);
      }
    }
  }
}
          

$ javac C.java 
C.java:7: error: variable x is already defined in method f()
        int x = y + 1;
            ^
1 error
          

Shadowing - Java

  • Fields have different treatment

public class C {
  static int x = 1;
  static void f () {
    int y = x + 1;
    {
      int x = y + 1;
      System.out.println ("x = " + x);
    }
  }
  public static void main (String[] args) {
    f ();
  }
}
          

$ javac C.java 
$ java C
x = 3
          

Shadowing C

  • C is less strict than Java (on shadowing)

int main () {
  int x = 1;
  {
    int y = x + 1;
    {
      int x = y + 1;
      printf ("x = %d\n", x);
    }
  }
}
          

$ gcc -o scope scope.c 
$ ./scope
x = 3
          

Shadowing Lox

  • Lox is like C for local definitions

fun f () {
  var x = 1;
  {
    var y = x + 1;
    {
       var x = y + 1;	 
       print x;
    }
  }
}
f();
          

3
          

Shadowing Lox

  • Lox does not shadow in the REPL, it overwrites

> var x = 1;
> fun f(a) { return x + a; }
> print f(10);
11
> var x = 1000;
> print f(10);
1010
          

Shadowing and Recursion in C

  • Is x in scope?

int main (void) {
  int x = 10;
  {
    int x = x + 1;
    printf ("x = %08x\n", x);
  }
  return 0;
}
          

$ gcc -o scope scope.c

$ gcc -Wall -o scope scope.c
scope.c: In function ‘main’:
scope.c:5:7: warning: unused variable ‘x’ [-Wunused-variable]
scope.c:7:9: warning: ‘x’ is used uninitialized in this function [-Wuninitialized]

$ ./scope 
x = 00000001
          

Shadowing and Recursion in Lox

  • Is x in scope?

> var x = 1;
> fun f(a) { var x = x + 1; return x; }
          

[line 1] Error at 'x': Can't read local variable in its own initializer.