Path: utzoo!attcan!uunet!lll-winken!lll-tis!ames!haven!adm!smoke!gwyn From: gwyn@smoke.BRL.MIL (Doug Gwyn ) Newsgroups: comp.std.c Subject: Re: A Little Quibble Message-ID: <9132@smoke.BRL.MIL> Date: 10 Dec 88 02:18:45 GMT References: <25200001@uicsrd.csrd.uiuc.edu> <25200002@uicsrd.csrd.uiuc.edu> Reply-To: gwyn@brl.arpa (Doug Gwyn (VLD/VMB) ) Organization: Ballistic Research Lab (BRL), APG, MD. Lines: 66 In article <25200002@uicsrd.csrd.uiuc.edu> mcdaniel@uicsrd.csrd.uiuc.edu writes: >#include >int a = 1; EXTERNAL LINKAGE FILE SCOPE STATIC STORAGE DURATION TYPE int NAME "a" INITIALIZED TO THE VALUE 1 BEFORE PROGRAM EXECUTION STARTS >main() > { > int a = 2; /* Y */ NO LINKAGE BLOCK Y SCOPE (hides file-scope declaration of "a") AUTOMATIC STORAGE DURATION TYPE int NAME "a" RUN-TIME INITIALIZED TO THE VALUE 2 WHENEVER THIS POINT IS EXECUTED > { > extern int a; /* Z */ EXTERNAL LINKAGE (since no visible file-scope declaration of "a") BLOCK Z SCOPE (hides both other declarations of "a") STATIC STORAGE DURATION TYPE int NAME "a" NO INITIALIZATION PERFORMED > printf("%d\n", a); This identifier "a" must be the block-Z declared one. Further, all external-linkage "a"s in all combined translation units and libraries must denote the same object. Therefore, "1" followed by a new-line must be printed. > } Block-Y-scope declared "a" is back in scope now. > } File-scope declared "a" is back in scope now. >On the VAX BSD 4.3 compiler, it complaints about line Z (redeclaration of a). That should be a lint-like usage warning, not a true diagnostic message. The usage is legal C, but possibly a slip-up by the programmer. >What if I change line Z to "extern const int a;"? Qualified and unqualified versions of a type are distinct types belonging to the same type category. They do not have compatible types. Therefore the behavior is undefined. > #include > main() { > int a; a = 1; > { int a = a; printf("a=%d\n", a); } > exit(0); > } >The BSD 4.3 compiler apparently evaluates the right-hand side of > int a = a; >in the context of the current block (as if it were > int a; a = a; >); this program does not output "1". Yes, that's correct. The identifier's scope starts right after its declarator (i.e. before its initializer). The initializer must use the newly-introduced "a", not one that is not currently in scope. Since the new object named "a" has not been given a value, random junk may be printed (or other undefined behavior may occur). All this stuff is covered in section 3.1.2 of the draft proposed ANSI C standard.