rws@EXPO.LCS.MIT.EDU (Bob Scheifler) (12/30/88)
#define foo "abcde" Is sizeof(foo) defined to be 5, 6, or >=5? My Sun compiler gives 6, I have a bug report claiming it should be 5, and the C manuals I have are no help.
spaf@cs.purdue.edu (Gene Spafford) (12/30/88)
In article <8812300028.AA17754@EXPO.LCS.MIT.EDU> rws@EXPO.LCS.MIT.EDU (Bob Scheifler) writes: >#define foo "abcde" >Is sizeof(foo) defined to be 5, 6, or >=5? My Sun compiler gives 6, >I have a bug report claiming it should be 5, and the C manuals I have >are no help. It's 6. The string "abcde" defines 6 storage locations (the trailing null is one of them), so the size of the array so defined is 6 characters. If you do the following: int arr[3]; printf("%d\n", sizeof(arr)); you should get 3 * sizeof(int) (12 on a Sun or Vax). In general, sizeof (array_name) = (number_of_elements * sizeof_element). A literal string in a special case of this. -- Gene Spafford NSF/Purdue/U of Florida Software Engineering Research Center, Dept. of Computer Sciences, Purdue University, W. Lafayette IN 47907-2004 Internet: spaf@cs.purdue.edu uucp: ...!{decwrl,gatech,ucbvax}!purdue!spaf
bzs@Encore.COM (Barry Shein) (01/01/89)
From: rws@EXPO.LCS.MIT.EDU (Bob Scheifler) >#define foo "abcde" >Is sizeof(foo) defined to be 5, 6, or >=5? My Sun compiler gives 6, >I have a bug report claiming it should be 5, and the C manuals I have >are no help. from "A C Reference Manual", Harbison and Steele, pg. 22 "The type of a string constant is ``array of char,'' and its value is the n+1 characters. For example, the value of sizeof("abcdef") is 7..." K&R (either edition) doesn't seem to say anything explicit but the fact that "xyz" is of type "array of char" and that a null is added by the compiler is quite clear, I can't imagine any argument which says that null is then somehow ignored by sizeof() (how would it know?) I'm pretty sure the confusion, if any, is some belief that strlen("abc") should return the same result as sizeof("abc") which is false. What's worse are compilers (known to exist!) which return sizeof(char *) for sizeof(string constant), that is unacceptable but worth a moment's thought when relying on these semantics or trying to track down a problem. -Barry Shein, ||Encore||
rws@EXPO.LCS.MIT.EDU (Bob Scheifler) (01/01/89)
I'm pretty sure the confusion, if any, is some belief that strlen("abc") should return the same result as sizeof("abc") which is false. My confusion was more looking at K&R, p99, which says "the compiler terminates the array with the character \0 so that programs can find the end". It wasn't clear whether "terminates" meant that it was considered "inside" or "outside" the array. It goes on to say "The length in storage is thus one more than ..." But I noted that it was (careful/careless) to say "length in storage" rather than "length of the array". What's worse are compilers (known to exist!) which return sizeof(char *) for sizeof(string constant), that is unacceptable but worth a moment's thought when relying on these semantics or trying to track down a problem. I'm getting pretty tired of working around broken compilers ...
casey@gauss.llnl.gov (Casey Leedom) (01/01/89)
| From: bzs@Encore.COM (Barry Shein) | | What's worse are compilers (known to exist!) which return sizeof(char *) | for sizeof(string constant), that is unacceptable but worth a moment's | thought when relying on these semantics or trying to track down a problem. Unacceptable in the sense that all C compilers that I know of return n+1 instead of sizeof(char *) giving us a ``common law'' standard, but the second interpretation is just as consistent as the first if not more so. K&R allows us to do both of the following: 1. char s[] = "..."; 2. char *t = "..."; Is "..." really just shorthand for ``{ '.', '.', '.' }'', or is it a directive to the compiler to find some space somewhere (n+1 in size) and then replace the reference to the double quoted object with a char * pointer to that space? Throughout C, there are in fact more instances of the second than there are of the first. I can pass "..." as an argument to a function and get the second interpretation, but not the first for instance. In some ways interpreting sizeof("...") to be sizeof(char *) would be more consistent, but certainly less useful. Casey
bzs@Encore.COM (Barry Shein) (01/02/89)
> Throughout C, there are in fact more instances of the second than there >are of the first. I can pass "..." as an argument to a function and get >the second interpretation, but not the first for instance. In some ways >interpreting sizeof("...") to be sizeof(char *) would be more consistent, >but certainly less useful. > >Casey Based on that reasoning we would expect for: int a[10]; sizeof(a) to be sizeof(int *)? After all "abcd" is just array of char and calling a subroutine foo(a) passes an int *. Remember, sizeof is NOT A SUBROUTINE, it's an operator and: i = sizeof "foo"; i = sizeof (char *); /* the parens are part of the cast */ are perfectly legal, as is -(i) (ie. you can make unary ops look like subroutines in general, sizeof("foo") just adds gratuitous parens.) Thus, it can have its own semantics, and does, you're looking for consistency where none is needed. -Barry Shein, ||Encore||
casey@gauss.llnl.gov (Casey Leedom) (01/02/89)
| From: bzs@Encore.COM (Barry Shein) | | | From: Casey Leedom <casey@lll-crg.llnl.gov> | | | | In some ways interpreting sizeof("...") to be sizeof(char *) would be | | more consistent, but certainly less useful. | | Based on that reasoning we would expect for: ``int a[10];'' sizeof(a) to | be sizeof(int *)? [Sizeof is not a subroutine, it's an operator.] Thus, | it can have its own semantics, and does, you're looking for consistency | where none is needed. Right as usual Barry. I should have remembered that the basic semantic meaning of ``sizeof foo'' is size of the OBJECT foo. Sizeof (char *), etc. is just asking what the size of an abstract OBJECT of type (char *), etc. would be. Thus sizeof(char [10]) returns 10 for the abstract OBJECT which is an array of 10 characters. Casey