home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / comp / lang / c / 16906 < prev    next >
Encoding:
Text File  |  1992-11-20  |  4.5 KB  |  122 lines

  1. Path: sparky!uunet!think.com!ames!agate!dog.ee.lbl.gov!horse.ee.lbl.gov!torek
  2. From: torek@horse.ee.lbl.gov (Chris Torek)
  3. Newsgroups: comp.lang.c
  4. Subject: Re: Where are literals stored?
  5. Date: 20 Nov 1992 21:17:46 GMT
  6. Organization: Lawrence Berkeley Laboratory, Berkeley
  7. Lines: 109
  8. Message-ID: <27583@dog.ee.lbl.gov>
  9. References: <27542@dog.ee.lbl.gov> <By0vzy.4Ly@ocsmd.ocs.com>
  10. Reply-To: torek@horse.ee.lbl.gov (Chris Torek)
  11. NNTP-Posting-Host: 128.3.112.15
  12.  
  13. In article <27542@dog.ee.lbl.gov> I wrote:
  14. >>String literals are formed from quoted strings that appear in a
  15. >>value context, e.g.,
  16. >>     char *p, *q;
  17. >>     p = "ABC";
  18. >>     q = "ABC";
  19. >>
  20. >>     /* it is unspecified whether p == q */
  21.  
  22. In article <By0vzy.4Ly@ocsmd.ocs.com> ted@ocsmd.ocs.com (Ted Scott) writes:
  23. >Ok, *I'm* confused here. Does this mean that if I do something like:
  24. >
  25. > *p[1] = ' '; 
  26. >
  27. >q will now point to "A C" ??
  28.  
  29. Since p[1] is a value of type `char', *p[1] is illegal: the operand of
  30. a unary `*' indirection operator must have type `pointer to T', for some
  31. valid type T.
  32.  
  33. Assuming you meant
  34.  
  35.     p[1] = ' ';
  36.  
  37. >or will the above assignment yield a SEGV? or what? (I know probably what :)
  38.  
  39. Yes, `or what' :-) .  In ANSI C, the effect is explicitly undefined;
  40. *anything* can happen.  Your computer might suddenly quote King Lear
  41. (`old Tom's a-cold!').  If this were comp.std.c we could stop there,
  42. but...:
  43.  
  44. >To carry this on further, what if p and q are in different scope, but the 
  45. >same source file?
  46.  
  47. The scope and duration of p and q are irrelevant until we limit ourselves
  48. to specific implementations.
  49.  
  50. Given the code fragment:
  51.  
  52.     char *p = "ABC";
  53.     p[1] = ' ';
  54.  
  55. one of three effects is likely:
  56.  
  57.     1) p[1] (which was 'B') is replaced by the code for ' ',
  58.        so that p points to "A C".
  59.     2) The program aborts (e.g., segmentation fault).
  60.     3) The program continues, but p[1] remains 'B'.
  61.  
  62. Effect (1) occurs in a number of implementations, all of which simply
  63. put string literals somewhere in RAM.  Effect (2) occurs on many
  64. quality UNIX C implementations, all of which simply put string literals
  65. somewhere in the read-only protected text space.  Effect (3) occurs
  66. on most embedded implementations, which simply put string literals
  67. somewhere in ROM.
  68.  
  69. Now, with effects (2) and (3), if we have:
  70.  
  71.     char *q = "ABC";
  72.  
  73. anywhere else in the same program, we will not be able to see any
  74. change, because there *was* no change (either the program aborted or
  75. the write attempt was ignored).  So let us assume we see effect (1).
  76. What happens to q?
  77.  
  78. This time the effect depends on exactly *where* string literals go
  79. ---which was part of the original question.  Again, it is unanswerable
  80. without referring to specific implementations.
  81.  
  82. Some compilers, particularly those which attempt to save space in the
  83. final executable, will `remember' every string literal as it appears in
  84. the source, and will make only one copy of each distinct literal.  In
  85. this case, given
  86.  
  87.     char *p = "ABC", *q = "ABC";
  88.  
  89. we will have p == q and (assuming effect (1)) both will point to "A C"
  90. after the assignment (p[1] = ' ').
  91.  
  92. If p and q are separated by some distance---say, a scope block or
  93. separate source files---whether they will still compare equal depends
  94. on just how much effort the compiler puts into conserving space.  It is
  95. not too difficult to keep a complete table of every string in every
  96. single source file; any compiler that defers code generation until
  97. `link' time is capable of arranging for p==q even if p and q are in
  98. separate files, or even if one (or both) is in a library.  The reward
  99. for this effort is typically fairly small, however, and I know of no
  100. compilers that do it.  (This does not mean that none exist.)
  101.  
  102. That said, in a compiler for which compile-time space is not a serious
  103. issue (e.g., GCC), it is reasonable for the compiler to remember every
  104. string literal in a single source file.  In this case, p==q iff the two
  105. "ABC"s appear in the same source file.  Those who want better string
  106. optimization can use `helper' programs like the BSD UNIX `xstr'.
  107.  
  108. Incidentally, note that even xstr is suboptimal: it does not catch
  109. libraries, and it given something like:
  110.  
  111.     char *p = "world", *q = "Hello world";
  112.  
  113. it misses the chance to make the `world's overlap.  (It catches them
  114. when they appear in the other order.  To do a better job, xstr should
  115. read the entire file, then sort literals by length before attempting to
  116. combine tails.)  It is not completely clear whether merging overlapping
  117. literals is permitted by the ANSI standard, but I would not object to a
  118. compiler that did so.
  119. -- 
  120. In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 510 486 5427)
  121. Berkeley, CA        Domain:    torek@ee.lbl.gov
  122.