[comp.windows.x] stupid C question

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