Return to BSD News archive
Path: sserve!manuel.anu.edu.au!munnari.oz.au!spool.mu.edu!sol.ctr.columbia.edu!usc!cs.utexas.edu!sun-barr!ames!agate!dog.ee.lbl.gov!horse.ee.lbl.gov!torek From: torek@horse.ee.lbl.gov (Chris Torek) Newsgroups: comp.unix.bsd Subject: Re: mktemp - Bus Error. Date: 6 Nov 1992 12:29:24 GMT Organization: Lawrence Berkeley Laboratory, Berkeley Lines: 88 Message-ID: <27268@dog.ee.lbl.gov> References: <KHERA.92Nov3111245@thneed.cs.duke.edu> <1992Nov3.174359.19262@Princeton.EDU> <9231017.24452@mulga.cs.mu.OZ.AU> <1992Nov5.180007.28471@fcom.cc.utah.edu> Reply-To: torek@horse.ee.lbl.gov (Chris Torek) NNTP-Posting-Host: 128.3.112.15 In article <1992Nov5.180007.28471@fcom.cc.utah.edu> terry@cs.weber.edu (A Wizard of Earth C) writes: >Several compilers treat: > char tmpname[] = "/tmp/foo.XXXXXX"; >as if it were: > char *tmpname = "/tmp/foo.XXXXXX"; Any compiler that does so is horribly broken. >...the second is, of course, legal. The first is also legal, provided that: a) the compiler claims to be ANSI X3.159-1989 (`ANSI C') conformant; or: b) the array "tmpname" has static duration. (This is an inclusive `or'.) > char *foo = "Hello World" + 6; > > printf( "%s\n", foo); /* prints "World\n"*/ > printf( "%s\n", foo - 6); /* depends on code generation*/ This is entirely wrong. The type of a string literal is now and has always been `array N of char'. (There have been a few compilers that got this wrong, but they were/are broken and essentially irrelevant. No BSD compiler has been broken in this way.) The characters themselves may be kept in read-only storage---this is the default under GCC, and is permitted by the ANSI C standard---or in read/write storage. The old PCC-based BSD compilers did the latter, and GCC will also do so if you use `-fwritable-strings'. Writable string literals are permitted by the ANSI standard---it does not pin implementations down either way---but since they *might* be read-only, you should treat them as read-only. Note that the "/tmp/foo.XXXXXX" in char tmpname[] = "/tmp/foo.XXXXXX"; is *NOT* a string literal, despite the syntactic resemblance. (It is an initializer.) >... If the compiler generates code the K&R/Portable C compile way, the >second printf() will print "Hello World\n"; otherwise, what it does is >not defined (for instance, Microsoft C). If MicroSoft C version x.y does not print "Hello World\n", MicroSoft C version x.y is broken. (This would come as no surprise to anyone who has ever tried to use MicroSoft C for large projects. Note that a broken compiler can still be useful. The two are not entirely orthogonal, but neither are they mutually contradictory.) >... you should be able to use: > > char *p; > > p = mktemp( "/tmp/foo.XXXXXX"); > >without ill effect. Not so. If the characters are kept in read-only storage, as permitted by the ANSI standard, this constitutes an attempt to modify a non-modifiable object. The result is, according to the ANSI standard, undefined. A bus error and core dump is a perfectly valid result. The compiler cannot diagnose an error here because the type of a string literal is `array N of char', not `array N of read-only char', even when the individual `char's are read-only. This is a consequence of ANSI C's type compatibility rules: if the type of the array were `const char [N]', code of the form: char *space = " "; would require a diagnostic. (This could have been avoided by adding special case rules, or by allowing `const char *q; p = q;', but the members of X3J11 did neither.) GCC nevertheless allows you to obtain a warning anyway: the `-Wwrite-strings' option tells the compiler to use the const qualifier for string literal types. This is not strictly conformant---although there is no way to tell, since compilers may issue bogus warnings at any time without violating the ANSI standard---and will, as the manual warns, merely be a nuisance unless you are *really* picky about using const qualifiers, but there it is. (You might also want to use `-Wcast-qual'.) -- In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 510 486 5427) Berkeley, CA Domain: torek@ee.lbl.gov