Path: utzoo!attcan!utgpu!jarvis.csri.toronto.edu!clyde.concordia.ca!uunet!mailrus!purdue!haven!adm!smoke!gwyn From: gwyn@smoke.BRL.MIL (Doug Gwyn) Newsgroups: comp.std.c Subject: Re: variable-length struct hack Message-ID: <11768@smoke.BRL.MIL> Date: 8 Dec 89 01:48:16 GMT References: <448@longway.TIC.COM> <450@longway.TIC.COM> <15364@haddock.ima.isc.com> Reply-To: gwyn@brl.arpa (Doug Gwyn) Organization: Ballistic Research Lab (BRL), APG, MD. Lines: 43 In article <15364@haddock.ima.isc.com> karl@haddock.ima.isc.com (Karl Heuer) writes: >9. Hence, strcpy(p->name, s) is legal. I basically agree with the argument to this point, which is as far as you took it. However, the next step might be to access p->name[n], where n > 0, and that is technically illegal since the `name' member is an array of length 1, so [0] is the last legally accessible element in it. A conforming implementation could, so far as I can tell, enforce bounds checking on such an array access. I think Dennis believes that too. >So it would appear that Doug's implementation of will work on any >ANSI C implementation. Have I overlooked anything? I think my implementation functions properly internally, for the reasons you spelled out in deriving conclusion 9 above, but the real question is whether the user of the dirent facilities can then deal with the struct dirent to which readdir() returns a pointer in a useful way. I believe Dennis is correct in having misgivings about this trickery, not because the implementation will malfunction, but because in some environments the struct dirent user might get screwed by this kludge. (I believe that so long as he merely uses strcpy() etc. to handle the d_name field, he'll be okay; it's direct access of the d_name[] elements that might go wrong.) I don't think IEEE Std 1003.1 guarantees that all the useful information for a directory entry is contained entirely within the declared struct dirent type, but it also doesn't warn the user about this issue, so it is quite likely that somebody will attempt to copy the information using normal C operations such as struct dirent mycopy = *p; then use the copy, with unpredictable results. Absent a clear statement of intent, it is impossible to determine whether this was supposed to work or not. From my involvement in thrashing out the dirent specs, my clear recollection is that the d_name[1] trick was specifically catered for, meaning that mycopy=*p is not meant to be guaranted to work, but I admit that this may well come as a surprise to the reader of Std 1003.1 as it now stands. I think that this whole topic is awfully messy. I am not "embarrassed" to have used this trick, for reasons I explained in a previous posting. However, I do plan on making reliance on the trick an option, rather than forced, in a future version of my PD dirent implementation. That way the installer can, in an environment where array bounds checking is enforced, decide whether or not to trade off space for user convenience.