[net.lang.c] sizeof "string"? multi-line macro usage?

colin@vu-vlsi.UUCP (07/12/86)

Question 1.

Is it (portably) legal for sizeof to operate on a string constant?  I
checked K&R, and they seem to have nothing to say about the subject.
Admittedly, string constants are weird because they're the only valid
array constants in the language, right?  That is, they evaluate to pointers
just like other arrays do, but they magically find some memory for themselves,
whereas other arrays are only allocated memory when they're declared.
This came up because I have coded

#define PROMPT "prog> "

in an include file, and then later used 

for (i = 0; i < sizeof(PROMPT) - 1; i++)	/* indent to first char of input */
	putchar(' ');

to get the proper indentation for error messages.  This worked great when
compiled on Pyramid C, VAX VMS C, and Lattice C on a PC.  Then I ran into the
Regulus C compiler (Regulus 4.2C) which is truly brain-damaged in many
respects; as far as I can tell, its sizeof returns a random value when given
a string.  So is it just Regulus that's screwed up, or do I have to explicitly
declare

char prompt[] = PROMPT;

and then take sizeof(prompt)?  (The latter _does_ work in Regulus.)


Question 2.

Does ANSI say anything about macro usage spanning more than one line?  Lattice
C has something like

#define max(a,b) ((a > b) ? a : b)

but then barfs when I use the macro over more than one line, like

x = min(very-long-expression-here,
	another-very-long-expression-here);

All the other compilers I've used have no trouble with this.  (By not allowing
multi-line macro usage, Lattice is screwing with the usually transparent
interchangeability of functions and macros...)

Anyone know the correct answer to these questions?  Thanks...

			-Colin Kelley ..{cbmvax,pyrnj,psuvax1}!vu-vlsi!colin

greg@utcsri.UUCP (Gregory Smith) (07/13/86)

In article <343@vu-vlsi.UUCP> colin@vu-vlsi.UUCP writes:
>Question 1.
>
>Is it (portably) legal for sizeof to operate on a string constant?  I
>checked K&R, and they seem to have nothing to say about the subject.
..
>This came up because I have coded
>
>#define PROMPT "prog> "
>
>in an include file, and then later used 
>
>for (i = 0; i < sizeof(PROMPT) - 1; i++)	/* indent to first char of input */
>	putchar(' ');
>
>to get the proper indentation for error messages.  This worked great when
>compiled on Pyramid C, VAX VMS C, and Lattice C on a PC.  Then I ran into the
>Regulus C compiler (Regulus 4.2C) which is truly brain-damaged in many
>respects; as far as I can tell, its sizeof returns a random value when given
>a string.

Regulus is screwed up.
BTW,
	printf( "%*s",sizeof(PROMPT)-1, " ");
will work except that Regulus may not support * in formats.
Or if you want to get really efficient at the expense of weirdness:

	printf( "                    "+20-( sizeof(PROMPT)-1 ) );

>So is it just Regulus that's screwed up, or do I have to explicitly
>declare
>
>char prompt[] = PROMPT;
>
>and then take sizeof(prompt)?  (The latter _does_ work in Regulus.)
>
Interestingly, using PCC, sizeof("foobar") gives 7 but stuffs the string
"foobar" into memory which will never be used, so you may as well use the
prompt[] solution above. This may depend on the dialect of PCC you are using,
but all of ours do, and so does cc11 (PDP11). Dem bugs, dem bugs....

>
>Question 2.
>
>Does ANSI say anything about macro usage spanning more than one line?  Lattice
>C has something like
>
>#define max(a,b) ((a > b) ? a : b)
>
>but then barfs when I use the macro over more than one line, like
>
>x = min(very-long-expression-here,
>	another-very-long-expression-here);
>
>All the other compilers I've used have no trouble with this.  (By not allowing
>multi-line macro usage, Lattice is screwing with the usually transparent
>interchangeability of functions and macros...)
>
This is #definitely a preprocessor bug.

-- 
"You'll need more than a Tylenol if you don't tell me where my father is!"
						- The Ice Pirates
----------------------------------------------------------------------
Greg Smith     University of Toronto      UUCP: ..utzoo!utcsri!greg

ron@brl-sem.UUCP (07/14/86)

In article <343@vu-vlsi.UUCP>, colin@vu-vlsi.UUCP (Colin Kelley) writes:
> Question 1.
> 
> Is it (portably) legal for sizeof to operate on a string constant?
Yes, "A string is a sequence of characters surrounded by double quotes
[and] has type 'array of characters.'" and "[Sizeof] when applied
to an array, the result is the total number of bytes in the array."
Hence,
	sizeof "foo"
should return 4.

ark@alice.UUCP (07/14/86)

re: is sizeof("...") legal?

> This worked great when
> compiled on Pyramid C, VAX VMS C, and Lattice C on a PC.  Then I ran into the
> Regulus C compiler (Regulus 4.2C) which is truly brain-damaged in many
> respects; as far as I can tell, its sizeof returns a random value when given
> a string.  So is it just Regulus that's screwed up ... ?

If you want your code to work on a particular compiler,
then the language definition doesn't matter if that compiler
doesn't accept it.  Thus, although K&R says:

	A string has type ``array of characters'' ...  (p. 181)

and

	When [sizeof is] applied to an array, the result
	is the total number of bytes in the array.

and thus one should conclude that sizeof("...") is legal,
that doesn't do you a bit of good if your compiler doesn't like it.

chris@umcp-cs.UUCP (07/14/86)

In article <343@vu-vlsi.UUCP> colin@vu-vlsi.UUCP (Colin Kelley) writes:
>Is it (portably) legal for sizeof to operate on a string constant?  I
>checked K&R, and they seem to have nothing to say about the subject.

K&R, by the inclusion of an explanatory sentence, made it ambiguous.
Appendix A, \S 7.1, Primary expressions, p. 186:

  A string is a primary expression.  Its type is originally ``array
  of char''; but following the same rule given above for identifiers,
  this is modified to ``pointer to char'' and the result is a pointer
  to the first character in the string.  (There is an exception in
  certain initializers; see \S 8.6.)

Had they left out the note about conversion to `pointer to char',
or had they mentioned sizeof in that last sentence, it would not
be ambiguous.  The ANSI draft standard simply declares a string
constant to have the type `array of char', making
`sizeof "foo the bar"' definitely equal to 12*sizeof(char).

>... This came up because I have coded
>
>#define PROMPT "prog> "
>
>in an include file, and then later used 
>
>for (i = 0; i < sizeof(PROMPT) - 1; i++) /* indent to first char of input */
>	putchar(' ');

There is another reason to avoid this: each time you mention the
string, most compilers generate another instance of it.  Using

>char prompt[] = PROMPT;

not only
>... _does_ work in Regulus
but also may keep your data space usage lower.

		* * *

>Does ANSI say anything about macro usage spanning more than one line?

The way I read the draft standard,

>#define max(a,b) ((a > b) ? a : b)
>
>x = min(very-long-expression-here,
>	another-very-long-expression-here);

is legal; but this is not explicit.  It depends on allowing `a
sequence of tokens' to include a newline.
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 1516)
UUCP:	seismo!umcp-cs!chris
CSNet:	chris@umcp-cs		ARPA:	chris@mimsy.umd.edu