Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 06 Nov 2002 12:52:46 -0800
From:      Terry Lambert <tlambert2@mindspring.com>
To:        Marc Olzheim <marcolz@stack.nl>
Cc:        hackers@FreeBSD.ORG
Subject:   Re: /usr/src/ed/bin/re.c:99
Message-ID:  <3DC9811E.35657731@mindspring.com>
References:  <20021106164653.GA95733@stack.nl>

next in thread | previous in thread | raw e-mail | index | archive | help
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:

	<register value> = function(<register value>);

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:

		<register value>++;
		<register value>--;
		<register value> = function(<register value>);

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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?3DC9811E.35657731>