mcdaniel@uicsrd.csrd.uiuc.edu (12/08/88)
Suppose I compile the following program under some dpANS C compiler:
#include <stdio.h>
main()
{
int a;
a = 1;
{
int a = a; /* X */
printf("a=%d\n", a);
}
exit(0);
}
Does dpANS require that "1" be printed, or is the result not defined
by dpANS? In other words, in what environment is the right-hand-side
of line X evaluated?
Suppose I change line X to
int b = a; /* X' */
int a = b;
Does the result change? If the simplest translation
int b, a;
b = a; a = b;
is always done, the result is always undefined.
I ask this for two reasons:
- it's an interesting little quibble. :-)
- I would like to declare an invariant like this:
double nubie;
. . . compute nubie . . .
{const double nubie = nubie;
. . . here, nubie is invariant . . .
}
(I could also put "register" there to prevent passing "&nubie" to a
function to change it. This use would only be for a compiler that is
smart enough to do its own register allocation, and ignore me totally.
:-)
By the way, here's another place where "typeof" would be convenient.
I could use
#define FIX(x) const typeof(x) x = x;
and code the example as
{ FIX(nubie);
. . . invariant nubie . . .
}
Instead, I must use
#define FIX(type, x) const type x = x;
This is more error-prone, and it is harder to change the type of such
a FIXed variable.
--
Tim, the Bizarre and Oddly-Dressed Enchanter
Center for ||| Internet, BITNET: mcdaniel@uicsrd.csrd.uiuc.edu
Supercomputing ||| UUCP: {uunet,convex,pur-ee}!uiucuxc!uicsrd!mcdaniel
Research and ||| ARPANET: mcdaniel%uicsrd@uxc.cso.uiuc.edu
Development, ||| CSNET: mcdaniel%uicsrd@uiuc.csnet
U of Illinois ||| DECnet: GARCON::"mcdaniel@uicsrd.csrd.uiuc.edu"mcdaniel@uicsrd.csrd.uiuc.edu (12/09/88)
Please excuse more of my quibbling . . .
Is the program below legal under dpANS? Is it guaranteed to output 1?
#include <stdio.h>
int a = 1;
main()
{
int a = 2; /* Y */
{
extern int a; /* Z */
printf("%d\n", a);
}
}
On the VAX BSD 4.3 compiler, it complaints about line Z (redeclaration
of a). If line Y is changed to "extern int a;", though, it compiles
fine.
What if I change line Z to "extern const int a;"?
About my base note's program (here reprinted)
#include <stdio.h>
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".
--
Tim, the Bizarre and Oddly-Dressed Enchanter
Center for ||| Internet, BITNET: mcdaniel@uicsrd.csrd.uiuc.edu
Supercomputing ||| UUCP: {uunet,convex,pur-ee}!uiucuxc!uicsrd!mcdaniel
Research and ||| ARPANET: mcdaniel%uicsrd@uxc.cso.uiuc.edu
Development, ||| CSNET: mcdaniel%uicsrd@uiuc.csnet
U of Illinois ||| DECnet: GARCON::"mcdaniel@uicsrd.csrd.uiuc.edu"gwyn@smoke.BRL.MIL (Doug Gwyn ) (12/09/88)
In article <25200001@uicsrd.csrd.uiuc.edu> mcdaniel@uicsrd.csrd.uiuc.edu writes: >Does dpANS require that "1" be printed, or is the result not defined >by dpANS? It's undefined (use of an uninitialized auto in an initializer expression). Questions like this are resolved by the "scope rules". >Does the result change? Yes, now "a=1\n" must be printed. >- it's an interesting little quibble. :-) Not really. >- I would like to declare an invariant like this: > double nubie; > . . . compute nubie . . . > {const double nubie = nubie; > . . . here, nubie is invariant . . . > } Multiple use of the same name for different purposes in the same section of code is considered horrible style by every programmer I know.
davidsen@steinmetz.ge.com (William E. Davidsen Jr) (12/10/88)
In article <25200001@uicsrd.csrd.uiuc.edu> mcdaniel@uicsrd.csrd.uiuc.edu writes: | - I would like to declare an invariant like this: | double nubie; | . . . compute nubie . . . | {const double nubie = nubie; | . . . here, nubie is invariant . . . | } How about: #define nubie ((const int) nubie) or some such? I don't have the standard handy, but at worst I think you would have to use another name, although I think there was something about not recursively evaluating a macro... -- bill davidsen (wedu@ge-crd.arpa) {uunet | philabs}!steinmetz!crdos1!davidsen "Stupidity, like virtue, is its own reward" -me
gwyn@smoke.BRL.MIL (Doug Gwyn ) (12/10/88)
In article <25200002@uicsrd.csrd.uiuc.edu> mcdaniel@uicsrd.csrd.uiuc.edu writes: >#include <stdio.h> >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 <stdio.h> > 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.