Clemson University -- CPSC 231 -- Spring 2010 Scope (visibility) scope in C is simple: normal declaration inside a procedure is visible only within that procedure normal declaration outside a procedure is visible to all code below that point in that source file external declaration (extern) informs the linker of a reference to a non- static/non-local variable or function in another source file scope in assembly is similar: unless otherwise specified, symbols are visible only within the source file (thus, you can't use "loop" as a label twice within the same source file, but each separate source file can use "loop" as a local label) for external references (i.e., between source files) a pseudo-op is used in one source file to indicate the global availability of a symbol defined in that file (i.e., exporting the symbol) and another pseudo-op is used in another source file to indicate use of that symbol (i.e., importing that symbol); up to the linker to match the uses with the definitions in MASM, the two pseudo-ops PUBLIC and EXTERN are used for these purposes in SPARC assembly, .global is used both in the exporting file and in the importing file using MASM-like pseudo-ops: -- example corresponding C statements -- define(EXTERN,global) define(PUBLIC,global) file a: .EXTERN sqrt file d: extern double sqrt(double); /* usually omit "extern" here */ /* "static" means not public */ .EXTERN x extern int x; /* "referencing" */ /* declaration */ .section ".data" w: .word 0 int w; .section ".text" ... ... call sqrt z = sqrt (y); nop set x,%o0 w = x; ld [%o0],%x_r set w,%o1 ... st %x_r,[%o1] ... file b: .PUBLIC sqrt file e: double sqrt(double argument){ sqrt: ... ... file c: .PUBLIC x file f: int x; /* "defining" decl. */ .section ".data" x: .word 0 Many C compilers/linkers assume that global variables with the same name in multiple "defining declarations" (i.e., no extern keywords) are identical. The exception is when more than one of these identically- named variables is initialized. -- file global_a_part_1.c -- -- file global_a_part_2.c -- #include #include int a; int a; void subr( void ); void subr(){ a = 2; int main(){ printf("a in subr is %d\n",a); a = 1; } printf("a in main is %d\n",a); subr(); printf("a in main is %d\n",a); return 0; } % gcc global_a_part_1.c global_a_part_2.c % ./a.out a in main is 1 a in subr is 2 a in main is 2 C has static scoping, but there are languages with dynamic scoping, such as APL and Perl, in which the variable names have to be resolved at run time based on the current nesting level or call chain % cat scope_test.c #include char str[] = "Global!"; void print_it(){ printf("%s\n",str); } int main(){ { char str[] = "Local!"; print_it(); } print_it(); } % gcc scope_test.c % ./a.out Global! Global! % cat scope_test.pl $str = "Global!\n"; sub print_it { print $str; } { local $str = "Local!\n"; print_it(); } print_it(); % perl scope_test.pl Local! Global! [adapted from www.programmersheaven.com/mb/perl/82538/82538/dynamic-scope/]