From owner-freebsd-hackers Wed Nov 6 12:54:25 2002 Delivered-To: freebsd-hackers@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 1532037B401 for ; Wed, 6 Nov 2002 12:54:22 -0800 (PST) Received: from flamingo.mail.pas.earthlink.net (flamingo.mail.pas.earthlink.net [207.217.120.232]) by mx1.FreeBSD.org (Postfix) with ESMTP id 2B40143E8A for ; Wed, 6 Nov 2002 12:54:13 -0800 (PST) (envelope-from tlambert2@mindspring.com) Received: from pool0355.cvx40-bradley.dialup.earthlink.net ([216.244.43.100] helo=mindspring.com) by flamingo.mail.pas.earthlink.net with esmtp (Exim 3.33 #1) id 189XBf-0005Xn-00; Wed, 06 Nov 2002 12:54:07 -0800 Message-ID: <3DC9811E.35657731@mindspring.com> Date: Wed, 06 Nov 2002 12:52:46 -0800 From: Terry Lambert X-Mailer: Mozilla 4.79 [en] (Win98; U) X-Accept-Language: en MIME-Version: 1.0 To: Marc Olzheim Cc: hackers@FreeBSD.ORG Subject: Re: /usr/src/ed/bin/re.c:99 References: <20021106164653.GA95733@stack.nl> Content-Type: text/plain; charset=us-ascii Content-Transfer-Encoding: 7bit Sender: owner-freebsd-hackers@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG Marc Olzheim wrote: > .. > if ((nd = parse_char_class(++nd)) == NULL) { > .. > > Hmmm... is this legal ? > > http://www.eskimo.com/~scs/C-faq/q3.1.html seems to tell otherwise... The FAQ entry you reference has nothing to say about this at all... it has to do with whether the *location* of the lvalue is evaluate before or after a non-parenthetical post increment: a[i] = i++; That's totally different than: if ((nd = parse_char_class(++nd)) == NULL) { Whis is really: nd = parse_char_class(++nd); if (nd == NULL) { Where the value has to be evaluated before the function is called to obtain the rvalue to assign the lvalue, and the increment is a preincrement. Consider that the location of the lvalue 'nd' is not changed by the value of the increment, whether it be pre- or post-. There was a problem, at one point in time, with: = function(); in the Berkeley Portable C compiler; this is irrelevent for two reasons: 1) FreeBSD uses the GNU C compiler, which does not have a problem with this construct 2) The preincremenet would ensure that the bug was not triggered; a common way of working around the bug was: ++; --; = function(); FWIW, the bug in question is called "the Berkeley pop order bug", and existed on all Berkeley Portable C compiler derived compilers, including the Sun C compiler on SunOS 4.x, and, potentially later Sun operating systems. The specific problem is that the register was pushed for the call, and then popped after the call -- after the assign, instead of before the assign. This was particularly a problem in the X Widgets in the Motif 1.x implementations, which would not run very well on SunOS, until the code was manually rewritten (either to force the use of an auto variable, since it's a register pop-order problem, or to do the increment and decrement). People who want their code to be portable avoid the construct: x = function(x); if there's any danger at all that 'x' will be promoted to a register, and/or they expect their code to ever be compiled on a Berkeley Portable C compiler derived compiler. Most people don't actually care about portable code these days; as long as their code runs on Linux, it doesn't have to run elsewhere. There are similarly non-portable constructs, which are generally ignored by poor programmers; for example, the non-zeroing of a sockaddr_in structures before calling socket(2), which cause portability problems. Also use of non-functional unit scoped variable declarations in statement blocks, particularly registers, would result in register overwrites in Lattice C compiler (which is still sold under another name, these days). Unions and bit fields are also generally non-portable. Unaligned structure elements can cause access faults on some hardware (particularly Alpha, but also 486+, if you set the right bit into the control register). Not having a space in the right place around parenthesis does not work on some compilers; the FreeBSD style(9) actually insists that the code not be fortable to some compilers (e.g. where the token compare is agains "while(" instead of "while", the insistance on a space before the parenthesis ensures the code will not compile, or the use of the template member operator "::" not having a space before it will fail to compile properly in the GNU C++ compiler, prior to version 2.95, etc.). In any case, your fears are unfounded, for the most part, since the FAQ entry you are referencing is not analogous to the construct you are trying to apply it to, anyway, and the FAQ fails to deal with many of these portability issues, too, since it assumes that the compiler is to spec.. -- Terry To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-hackers" in the body of the message