brnstnd@kramden.acf.nyu.edu (Dan Bernstein) (02/02/91)
In article <1991Feb1.203935.18927@csrd.uiuc.edu> bliss@sp64.csrd.uiuc.edu (Brian Bliss) writes: > func f (const int *x, int *y); > then once the comipler fetches the value of *x, it need not fetch > it again in the subroutine, means it is constant. if it were not > constant, then we could potentially modify the value of *x by > assigning through *y (if x == y), and the compiler would need to > recalculate *x every time it was needed (if *y or any global variable > has been modified since the last calculation of *x). Wait a minute. I thought const was only a prohibitive qualifier (you can't set *x = foo) rather than an assertive qualifier (*x won't change while it's in scope). Aren't you allowed to call f(&z,&z) upon an int z (assuming prototypes are in scope), and doesn't f() have to reload *x every time? ---Dan
paul@tredysvr.Tredydev.Unisys.COM (Paul Siu) (02/02/91)
In ANSI C, you can define a variable as constant by preceeding it with const. You can for example define a double variable x that you cannot change by const double x; However, what is the advantage of using const over #define? Why was the reason for its addition to ANSI C. Paul Siu paul@tredysvr.tredydev.unisys.com
bliss@sp64.csrd.uiuc.edu (Brian Bliss) (02/02/91)
In article <1220@tredysvr.Tredydev.Unisys.COM>, paul@tredysvr.Tredydev.Unisys.COM (Paul Siu) writes: |> In ANSI C, you can define a variable as constant by preceeding it with const. |> You can for example define a double variable x that you cannot change by |> |> const double x; |> |> However, what is the advantage of using const over #define? Why was the |> reason for its addition to ANSI C. |> |> Paul Siu |> paul@tredysvr.tredydev.unisys.com because you can take the address of a variable declared as constant, but you can't take the address of a hard-coded constant. You can also declare const int *x; which means that the value to which x points will not be changed. therefore if you have: func f (const int *x, int *y); then once the comipler fetches the value of *x, it need not fetch it again in the subroutine, means it is constant. if it were not constant, then we could potentially modify the value of *x by assigning through *y (if x == y), and the compiler would need to recalculate *x every time it was needed (if *y or any global variable has been modified since the last calculation of *x). Not only that, but the type information for a symbol declared as const is included in the dbx symbol table information, and you can refer to that constant by name when debugging. What I welcome even more that the const declaration is the volatile declaration. Anyone who does parallel programming has run into the bug at a syncronization point: while (x); which means "wait unitl another processor changes the value of x to nonzero". unfortunately, many compilers do not re-fetch the value of x from memory each iteration of the loop (common subexpression elimination across loop iterations), and therefore go into an infinite loop. declaring x as volatile should tell the compiler that it's value can be changed without the current process doing so. bb
cc100aa@prism.gatech.EDU (Ray Spalding) (02/02/91)
In article <1220@tredysvr.Tredydev.Unisys.COM> paul@tredysvr.Tredydev.Unisys.COM (Paul Siu) writes: >However, what is the advantage of using const over #define? Why was the >reason for its addition to ANSI C. I believe "const" was added to (a) announce objects that may be placed in read-only memory, (b) provide possible opportunities for optimization, and (c) provide possible opportunities for diagnostics. These would all seem to be possible with #defines of simple constants like 3.14 or "abc" as well. But with "const", you can have read-only pointers, pointers to read-only objects, and read-only structs, arrays, etc. You can also take the address of a "const" variable (with &), but not of a literal constant. Of course, the "const" keyword is also used to denote that a function will not alter an array argument; a different usage but one that can be checked for optimizations and violations in a similar way by a compiler. -- Ray Spalding, Technical Services, Office of Information Technology Georgia Institute of Technology, Atlanta Georgia, 30332-0715 uucp: ...!{allegra,amd,hplabs,ut-ngp}!gatech!prism!cc100aa Internet: cc100aa@prism.gatech.edu
kdq@demott.com (Kevin D. Quitt) (02/03/91)
In article <1220@tredysvr.Tredydev.Unisys.COM> paul@tredysvr.Tredydev.Unisys.COM (Paul Siu) writes: >In ANSI C, you can define a variable as constant by preceeding it with const. >You can for example define a double variable x that you cannot change by > > const double x; > >However, what is the advantage of using const over #define? Why was the >reason for its addition to ANSI C. Your variable x above is pretty useless, since it has no initialized value (and is therefore zero). How about: const char *foo = "some really long string"; If this is #defined, and is accessed in several places, your compiler may save multiple copies of the string. Even if your compiler is smart enough to make it a single instance, it won't do this over several modules. Another advantage is in the optimization phases, where the const keyword provides more information to the optimizer. -- _ Kevin D. Quitt demott!kdq kdq@demott.com DeMott Electronics Co. 14707 Keswick St. Van Nuys, CA 91405-1266 VOICE (818) 988-4975 FAX (818) 997-1190 MODEM (818) 997-4496 PEP last
steve@taumet.com (Stephen Clamage) (02/05/91)
paul@tredysvr.Tredydev.Unisys.COM (Paul Siu) writes: >However, what is the advantage of using const over #define? Why was the >reason for its addition to ANSI C. A lot of good answers were posted to this question, but I didn't see any mention of scoping. Macros are not scoped. They exist from the textual point of declaration to the end of the compilation, unless #undef'd. So an innocent #define buried somewhere in the program (inside a function, or in a nested include file) can unintentionally affect later code. -- Steve Clamage, TauMetric Corp, steve@taumet.com
greywolf@unisoft.UUCP (The Grey Wolf) (02/06/91)
In article <1991Feb2.181948.2147@demott.com> kdq@demott.com (Kevin D. Quitt) writes: [ const double x; example deleted ] > Your variable x above is pretty useless, since it has no initialized >value (and is therefore zero). How about: > >const char *foo = "some really long string"; > > If this is #defined, and is accessed in several places, your >compiler may save multiple copies of the string. Even if your compiler >is smart enough to make it a single instance, it won't do this over >several modules. I know, I know, not ALL Unices are BSD, and not everyone can do this (yet), but there is something called xstr on most sensible systems which solves the #define problem quite nicely across multiple modules. for module in modules do cc -E $module.c | xstr - cc -c x.c mv x.o module.o mv x.c module.cx # (if you want to see what it's doing) done cc -c xs.c mv xs.o strings.o > > Another advantage is in the optimization phases, where the const keyword >provides more information to the optimizer. This does not get solved by xstr :-)... Where possible, the old method was to use cc -R on the resulting strings object (xs.o) to make the strings shared/read-only[*]. The C shell is compiled like this. What with the advent of ANSI C, it appears that the need for such a compiler flag has been obsoleted by the presence of the "const" qualifier. xstr still has its uses -- in places where quoted phrases might be used more than once (such as {fprintf(stderr,"ioctl: "); perror(arg);} sequences) all references to the quoted phrase would get changed to be pointers to the master string array. > > >-- > _ >Kevin D. Quitt demott!kdq kdq@demott.com >DeMott Electronics Co. 14707 Keswick St. Van Nuys, CA 91405-1266 >VOICE (818) 988-4975 FAX (818) 997-1190 MODEM (818) 997-4496 PEP last -- thought: I ain't so damb dumn! | Your brand new kernel just dump core on you war: Invalid argument | And fsck can't find root inode 2 | Don't worry -- be happy... ...!{ucbvax,acad,uunet,amdahl,pyramid}!unisoft!greywolf