Path: utzoo!utgpu!jarvis.csri.toronto.edu!mailrus!wuarchive!gem.mps.ohio-state.edu!tut.cis.ohio-state.edu!cica!iuvax!rutgers!att!cbnewsl!dfp From: dfp@cbnewsl.ATT.COM (david.f.prosser) Newsgroups: comp.lang.c Subject: Re: Help... Message-ID: <2199@cbnewsl.ATT.COM> Date: 10 Oct 89 15:41:27 GMT References: <731@carroll1.UUCP> Reply-To: dfp@cbnewsl.ATT.COM (david.f.prosser) Organization: AT&T Bell Laboratories Lines: 58 In article <731@carroll1.UUCP> dnewton@carroll1.cc.edu (Dave 'Yes, I'm weird' Newton) writes: >Why doesn't this work? > >========================== >#include >main () >{ > char h[]; > scanf ("%s", h); > printf ("%s\n", h); >} >========================== > > It seems innocent enuf, but just prints garbage. I'm missing something >obvious, but I'll be darned if I know what it is. The C compiler you are using allowed you to declare an automatic array of characters with an unspecified length. The behavior of such a program is undefined (and no diagnostic is required) according to the pANS. Section 3.5, page 58, lines 30-31 (semantics): If an identifier for an object is declared with no linkage, the type for the object shall be complete by the end of its declarator, or by the end of its init-declarator if it has an initializer. (An array with an unspecified length is an incomplete type.) What some compilers have done (still do) is declare a zero-sized object with an address on the stack. If you are unlucky, when the scanf call overwrites other parts of the stack, all that happens is that garbage is printed. What this program deserves is to dump core because the return address for scanf's stack frame is overwritten. This would let you know (quickly) that something pretty basic is wrong. A followup article asserted that "char h[];" in this context is the same as "char *h;". This is incorrect. The latter declares a pointer to one or more characters, but the value of the pointer is indeterminate (uninitialized); such a pointer, when passed to scanf, will likewise cause undefined behavior unless it is assigned a valid address. The former declaration, if accepted at all, most likely declares a zero- length array, but at least its address is known, and if carefully handled, can be useful. (But not in the above example.) Probably, this program wants a fixed-sized array of characters for h. The following includes this and a few other changes as well. #include main() { char h[1024]; if (scanf("%1023s", h) == 1) /* room for \0 */ printf("%s\n", h); return 0; } Dave Prosser ...not an official X3J11 answer...