ANSI-strict pointer aliasing rules

Lists: pgsql-hackers
From: Taral <taralx(at)gmail(dot)com>
To: pgsql-hackers(at)postgresql(dot)org
Subject: ANSI-strict pointer aliasing rules
Date: 2006-04-26 20:45:00
Message-ID: fa0147d90604261345s24b191bcj5a612cc918e31f1d@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

I ran afoul of these rules the other day when compiling pgsql 8.1 on
AIX. The configure scripts are set up to look for "xlc" instead of
"cc", and that command invokes cc with "-qalias=ansi", the ANSI-strict
pointer aliasing mode.

Specifically, in this mode, the compiler assumes that accesses via
pointers of different types never alias. Unfortunately, this breaks
all of the Value construction code, because we end up with (for
example):

Node *n = palloc0fast(...);
n->tag = T_VALUE;
Value *v = (Value *) n;
v->tag = T_STRING;

And aggressive compiler optimization can reorder these two tag
assignments, resulting in the bizarre "Unrecognized node type: 650"
message.

The fix is one of two things:

1. Change the "tag" element of structures to be a Node, and access the
tag via it: Major code change, allows Node to change in the future for
instrumentation et cetera.
2. Make the makeNode macro cast to the derived structure before
assigning the tag: Minor code change, makes assumptions about derived
structures.
3. Get configure to select "cc" instead of "xlc": No code change,
loses some performance.

--
Taral <taralx(at)gmail(dot)com>
"You can't prove anything."
-- Gödel's Incompetence Theorem


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Taral <taralx(at)gmail(dot)com>
Cc: pgsql-hackers(at)postgresql(dot)org
Subject: Re: ANSI-strict pointer aliasing rules
Date: 2006-04-26 20:58:31
Message-ID: 21138.1146085111@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

Taral <taralx(at)gmail(dot)com> writes:
> I ran afoul of these rules the other day when compiling pgsql 8.1 on
> AIX. The configure scripts are set up to look for "xlc" instead of
> "cc", and that command invokes cc with "-qalias=ansi", the ANSI-strict
> pointer aliasing mode.

We've looked at this before. There's no way we are buying into the
strict aliasing rules: it's not so much the code we know will break,
as the fear of what we don't know about. gcc, at least, is utterly
useless about warning about constructs that might change behavior
under strict aliasing ... but without fairly reliable warnings of
such problems, we have little hope of getting all the bugs out.

You'll notice that configure already goes out of its way to force
traditional aliasing for gcc, and I'd recommend doing the same for
AIX's compiler.

regards, tom lane


From: Martijn van Oosterhout <kleptog(at)svana(dot)org>
To: Taral <taralx(at)gmail(dot)com>
Cc: pgsql-hackers(at)postgresql(dot)org
Subject: Re: ANSI-strict pointer aliasing rules
Date: 2006-04-26 21:01:51
Message-ID: 20060426210151.GD11828@svana.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

On Wed, Apr 26, 2006 at 03:45:00PM -0500, Taral wrote:
> I ran afoul of these rules the other day when compiling pgsql 8.1 on
> AIX. The configure scripts are set up to look for "xlc" instead of
> "cc", and that command invokes cc with "-qalias=ansi", the ANSI-strict
> pointer aliasing mode.

PostgreSQL doesn't work with strict aliasing rules. That's why for GCC
we pass -fno-strict-aliasing. What's the equivalent option for that
compiler?

> The fix is one of two things:

Well, there are a number of fixes, it's questionable whether it's worth
the effort. In GCC you can mark structures that are aliased to avoid
the problem (attribute((may_alias)) iirc), but we don't do that.

> 3. Get configure to select "cc" instead of "xlc": No code change,
> loses some performance.

4. Find the option for disabling strict alias and get configure to add
that.

Have a nice day,
--
Martijn van Oosterhout <kleptog(at)svana(dot)org> http://svana.org/kleptog/
> From each according to his ability. To each according to his ability to litigate.


From: Martijn van Oosterhout <kleptog(at)svana(dot)org>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Taral <taralx(at)gmail(dot)com>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: ANSI-strict pointer aliasing rules
Date: 2006-04-26 21:16:12
Message-ID: 20060426211612.GE11828@svana.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

On Wed, Apr 26, 2006 at 04:58:31PM -0400, Tom Lane wrote:
> We've looked at this before. There's no way we are buying into the
> strict aliasing rules: it's not so much the code we know will break,
> as the fear of what we don't know about. gcc, at least, is utterly
> useless about warning about constructs that might change behavior
> under strict aliasing ... but without fairly reliable warnings of
> such problems, we have little hope of getting all the bugs out.

These warnings will never happen. Strict-aliasing could effect
anything, all you'd get would be zillions of useless warnings.

Take for example this innocuous looking code from libpq/hba.c:

static void
parse_hba_auth(ListCell **line_item, UserAuth *userauth_p,
char **auth_arg_p, bool *error_p)
{
char *token;

*auth_arg_p = NULL;

if (!*line_item)
{

Strict aliasing says that 'line_item' and 'auth_arg_p' can't point to
the same location because they are different types. Hence the
store/load could be overlapped safely. *We* know that will never be a
problem, but the compiler can't know, so it has to assume one way or
the other. With no-strict-aliasing, it can't reorder and it might add
wait-states instead, just in case (CPU dependant obviously).

The compiler could warn you about this, but it'd be useless since you
can't do anything about it anyway. In the grandparent's case I think
the compiler is being really stupid because it can know the two
pointers are the same. But I'm sure there are more subtle cases where
it won't know. PostgreSQL typecasts pointers fairly freely.

Have a nice day,
--
Martijn van Oosterhout <kleptog(at)svana(dot)org> http://svana.org/kleptog/
> From each according to his ability. To each according to his ability to litigate.


From: Taral <taralx(at)gmail(dot)com>
To: pgsql-hackers(at)postgresql(dot)org
Subject: Re: ANSI-strict pointer aliasing rules
Date: 2006-04-26 22:22:21
Message-ID: fa0147d90604261522rcd00a6eif3f0aecfba4132c7@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

On 4/26/06, Martijn van Oosterhout <kleptog(at)svana(dot)org> wrote:
> Well, there are a number of fixes, it's questionable whether it's worth
> the effort. In GCC you can mark structures that are aliased to avoid
> the problem (attribute((may_alias)) iirc), but we don't do that.

There's also C99's "restrict".

> 4. Find the option for disabling strict alias and get configure to add
> that.

You'll still lose performance, but the option is "-qalias=noansi".

--
Taral <taralx(at)gmail(dot)com>
"You can't prove anything."
-- Gödel's Incompetence Theorem


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Martijn van Oosterhout <kleptog(at)svana(dot)org>
Cc: Taral <taralx(at)gmail(dot)com>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: ANSI-strict pointer aliasing rules
Date: 2006-04-27 00:13:21
Message-ID: 1920.1146096801@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

Martijn van Oosterhout <kleptog(at)svana(dot)org> writes:
> In the grandparent's case I think
> the compiler is being really stupid because it can know the two
> pointers are the same. But I'm sure there are more subtle cases where
> it won't know. PostgreSQL typecasts pointers fairly freely.

Actually, if xlc is behaving as Taral says then I'm pretty convinced
it's *broken*; it is assuming far more than is allowed even by the ANSI
aliasing rules. As I read the spec, ANSI aliasing says that a given
value must always be accessed through equivalent (up to signedness)
primitive types, ie, if you store through an int pointer and fetch
through a long pointer the compiler is allowed to reorder those two
references. In the example Taral gives, both field references are to
fields of type NodeTag. I don't see anything in the spec that allows
the compiler to assume they are distinct variables just because they are
members of different struct types. The spec restriction is defined in
terms of the lvalue type of the particular store or fetch access, not on
what kind of structure it's part of.

regards, tom lane


From: Greg Stark <gsstark(at)mit(dot)edu>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Martijn van Oosterhout <kleptog(at)svana(dot)org>, Taral <taralx(at)gmail(dot)com>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: ANSI-strict pointer aliasing rules
Date: 2006-04-27 03:42:11
Message-ID: 87psj3adm4.fsf@stark.xeocode.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers


Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> writes:

> As I read the spec, ANSI aliasing says that a given value must always be
> accessed through equivalent (up to signedness) primitive types

It there a difference between C89 and C99 here?

--
greg


From: mark(at)mark(dot)mielke(dot)cc
To: Greg Stark <gsstark(at)mit(dot)edu>
Cc: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Martijn van Oosterhout <kleptog(at)svana(dot)org>, Taral <taralx(at)gmail(dot)com>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: ANSI-strict pointer aliasing rules
Date: 2006-04-27 05:00:26
Message-ID: 20060427050026.GA21084@mark.mielke.cc
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

On Wed, Apr 26, 2006 at 11:42:11PM -0400, Greg Stark wrote:
> Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> writes:
> > As I read the spec, ANSI aliasing says that a given value must always be
> > accessed through equivalent (up to signedness) primitive types
> It there a difference between C89 and C99 here?

I believe C89 makes no reference to aliasing restrictions. It only leaves
certain operations, in certain contexts, implementation defined. That is,
if you wish to maintain portable behaviour, you would choose not to make
use of C features that have implementation defined semantics... :-)

Cheers,
mark

--
mark(at)mielke(dot)cc / markm(at)ncf(dot)ca / markm(at)nortel(dot)com __________________________
. . _ ._ . . .__ . . ._. .__ . . . .__ | Neighbourhood Coder
|\/| |_| |_| |/ |_ |\/| | |_ | |/ |_ |
| | | | | \ | \ |__ . | | .|. |__ |__ | \ |__ | Ottawa, Ontario, Canada

One ring to rule them all, one ring to find them, one ring to bring them all
and in the darkness bind them...

http://mark.mielke.cc/


From: Martijn van Oosterhout <kleptog(at)svana(dot)org>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Taral <taralx(at)gmail(dot)com>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: ANSI-strict pointer aliasing rules
Date: 2006-04-27 07:24:14
Message-ID: 20060427072414.GB29830@svana.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

On Wed, Apr 26, 2006 at 08:13:21PM -0400, Tom Lane wrote:
> Actually, if xlc is behaving as Taral says then I'm pretty convinced
> it's *broken*; it is assuming far more than is allowed even by the ANSI
> aliasing rules. As I read the spec, ANSI aliasing says that a given
> value must always be accessed through equivalent (up to signedness)
> primitive types, ie, if you store through an int pointer and fetch
> through a long pointer the compiler is allowed to reorder those two
> references.

That's right, except I read "object", not "primative type". The
question revolves a bit around what an object is. This discussion on
the GCC lists [1] suggests that the syntax a->b is merely syntactic
sugar for (*a).b and thus the "object" being accessed is (*a), the type
of b is not relevent to the decision.

The standard [2] (at least that version) says:

3.14 object
region of data storage in the execution environment, the contents of
which can represent values

So is not limited to primitive types.

> In the example Taral gives, both field references are to
> fields of type NodeTag. I don't see anything in the spec that allows
> the compiler to assume they are distinct variables just because they are
> members of different struct types. The spec restriction is defined in
> terms of the lvalue type of the particular store or fetch access, not on
> what kind of structure it's part of.

Well, I imagine it doesn't help that the result of malloc(), which
normally can't alias anything, is assigned to a global variable of a
particular type, and subsequently cast to its actual type.

However, the posters original example doesn't exist in the current
codebase (we never assign T_String to a tag field, only to the type
field), so wherever the problem is, it's not here. At the end of the
day, our use of pointer casts makes the strict-aliasing rules a risk so
we're hardly likely to enable it anytime soon.

Have a nice day,

[1] http://gcc.gnu.org/ml/gcc/2003-02/msg01438.html
[2] http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf

Quotes from standard:

6.5 Expressions
7 An object shall have its stored value accessed only by an lvalue
expression that has one of the following types:

<rules>

6.3.2.1 Lvalues, arrays, and function designators

An lvalue is an expression with an object type or an incomplete type
other than void;
--
Martijn van Oosterhout <kleptog(at)svana(dot)org> http://svana.org/kleptog/
> From each according to his ability. To each according to his ability to litigate.


From: Andrew Dunstan <andrew(at)dunslane(dot)net>
To: Taral <taralx(at)gmail(dot)com>
Cc: pgsql-hackers(at)postgresql(dot)org
Subject: Re: ANSI-strict pointer aliasing rules
Date: 2006-04-27 10:04:19
Message-ID: 44509723.1040504@dunslane.net
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

Taral wrote:

>>4. Find the option for disabling strict alias and get configure to add
>>that.
>>
>>
>
>You'll still lose performance, but the option is "-qalias=noansi".
>
>
>
>

Next time we have this discussion I wish someone would actually document
the performance differences. IIRC most of what I have seen makes it at
best marginal.

Personally, I think this whole mess results from a bad case of
committee-itis.

cheers

andrew


From: Martijn van Oosterhout <kleptog(at)svana(dot)org>
To: Andrew Dunstan <andrew(at)dunslane(dot)net>
Cc: Taral <taralx(at)gmail(dot)com>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: ANSI-strict pointer aliasing rules
Date: 2006-04-27 10:52:42
Message-ID: 20060427105242.GF29830@svana.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

On Thu, Apr 27, 2006 at 07:34:19PM +0930, Andrew Dunstan wrote:
> Next time we have this discussion I wish someone would actually document
> the performance differences. IIRC most of what I have seen makes it at
> best marginal.

I can imagine there are cases where the performance difference is
nontrivial. Take this (somewhat contrived) example:

int *i;
char *c;
while( *i < BIG_NUMBER )
*i += *c;

With strict aliasing, the compiler need only load *c once, without it
needs to load it each time through the loop because it has to consider
the possibility that 'i' and 'c' point to the same memory location.

PostgreSQL doesn't actually have loops of this kind so it's not
something we need worry about. And you can acheive all the benefits by
explicitly loading *c into a local variable before the loop. I can
beleive that certain RISC architectures would benefit more than
something like the Intel CISC architecture.

> Personally, I think this whole mess results from a bad case of
> committee-itis.

I think the goal was noble (at least, according to the best version
I've heard so far): make it easier to compete with Fortran in numerical
processing. If you define a struct vector { double x,y,z,d; } and the
compiler can assume that values in that structure can only be changed
via a (vector*) pointer, it can do things like load an array of them
into a large parallel processing unit.

Ofcourse, this is useless for most of the programs written in C, and in
C99 they fixed it the right way using the "restrict" keyword, which is
actually far more usful for the above purpose than strict-aliasing.

Compiler writers love it because it makes it easier for them, but
actual benefits, hmm...

Have a nice day,
--
Martijn van Oosterhout <kleptog(at)svana(dot)org> http://svana.org/kleptog/
> From each according to his ability. To each according to his ability to litigate.


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Martijn van Oosterhout <kleptog(at)svana(dot)org>
Cc: Taral <taralx(at)gmail(dot)com>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: ANSI-strict pointer aliasing rules
Date: 2006-04-27 14:39:41
Message-ID: 10925.1146148781@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

Martijn van Oosterhout <kleptog(at)svana(dot)org> writes:
> That's right, except I read "object", not "primative type". The
> question revolves a bit around what an object is. This discussion on
> the GCC lists [1] suggests that the syntax a->b is merely syntactic
> sugar for (*a).b and thus the "object" being accessed is (*a), the type
> of b is not relevent to the decision.

The part of the spec that I'm looking at says

[#7] An object shall have its stored value accessed only by
an lvalue expression that has one of the following types:61)

-- a type compatible with the effective type of the
object,

-- a qualified version of a type compatible with the
effective type of the object,

-- a type that is the signed or unsigned type
corresponding to the effective type of the object,

-- a type that is the signed or unsigned type
corresponding to a qualified version of the effective
type of the object,

-- an aggregate or union type that includes one of the
aforementioned types among its members (including,
recursively, a member of a subaggregate or contained
union), or

-- a character type.

61)The intent of this list is to specify those circumstances
in which an object may or may not be aliased.

Which wouldn't be especially interesting, except for that footnote
(which in fact is one of only two uses of "alias" in the document;
there isn't any other discussion about aliasing at all).

As I read this, the aliasing rules are driven by the type of the
lvalue being fetched or assigned. Thus, when you fetch or assign a
whole struct, your reading would be correct, but not for a fetch
or assignment of a single struct field.

regards, tom lane


From: mark(at)mark(dot)mielke(dot)cc
To: Martijn van Oosterhout <kleptog(at)svana(dot)org>
Cc: Andrew Dunstan <andrew(at)dunslane(dot)net>, Taral <taralx(at)gmail(dot)com>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: ANSI-strict pointer aliasing rules
Date: 2006-04-27 14:43:59
Message-ID: 20060427144359.GA26734@mark.mielke.cc
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

On Thu, Apr 27, 2006 at 12:52:42PM +0200, Martijn van Oosterhout wrote:
> > Next time we have this discussion I wish someone would actually document
> > the performance differences. IIRC most of what I have seen makes it at
> > best marginal.
> I can imagine there are cases where the performance difference is
> nontrivial. Take this (somewhat contrived) example:
> int *i;
> char *c;
> while( *i < BIG_NUMBER )
> *i += *c;
> With strict aliasing, the compiler need only load *c once, without it
> needs to load it each time through the loop because it has to consider
> the possibility that 'i' and 'c' point to the same memory location.

> PostgreSQL doesn't actually have loops of this kind so it's not
> something we need worry about. And you can acheive all the benefits by
> ...

PostgreSQL might not - however PostgreSQL does use GLIBC, which does have
inlined or preprocessor defined code.

I haven't done the timings myself - but I think the optimization would
in theory apply to wider code than just the above. *c doesn't need to
be constant. It can be moving, as would be in the case of an strcpy()
or memcpy() implementation. As you pointed out, such things as
auto-vectorization become impossible if it cannot guarantee that the
data is different. The aliasing rules are one part, the 'restrict'
keyword is the more important part I would imagine. Not dissimilar to
the C compiler auto-assigning variables into registers, but allowing
for the designer to hint using the 'register' keyword.

In the modern day, I see fewer and fewer people using 'register', as
not only does the compiler tend to get it right, but the compiler
may actually do a better job. I could see the same thing being
true of auto-detect using aliasing rules vs 'restrict' keyword usage.

Even if it was only 1% - 2%. Isn't it worth it? :-) Especially for a
practice, that under existing code, has implementation defined
semantics. It might not work in the future, or with a new optimizer
mode that comes out, or a new platform...

Cheers,
mark

--
mark(at)mielke(dot)cc / markm(at)ncf(dot)ca / markm(at)nortel(dot)com __________________________
. . _ ._ . . .__ . . ._. .__ . . . .__ | Neighbourhood Coder
|\/| |_| |_| |/ |_ |\/| | |_ | |/ |_ |
| | | | | \ | \ |__ . | | .|. |__ |__ | \ |__ | Ottawa, Ontario, Canada

One ring to rule them all, one ring to find them, one ring to bring them all
and in the darkness bind them...

http://mark.mielke.cc/


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: mark(at)mark(dot)mielke(dot)cc
Cc: Martijn van Oosterhout <kleptog(at)svana(dot)org>, Andrew Dunstan <andrew(at)dunslane(dot)net>, Taral <taralx(at)gmail(dot)com>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: ANSI-strict pointer aliasing rules
Date: 2006-04-27 14:49:02
Message-ID: 11034.1146149342@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

mark(at)mark(dot)mielke(dot)cc writes:
> Even if it was only 1% - 2%. Isn't it worth it? :-)

No. According to the ancient saying, "I can make this program
arbitrarily fast ... if it doesn't have to give the right answer".
Percentage-point improvements are not worth the risk of introducing
hard-to-find, compiler-and-hardware-dependent bugs.

Show me how to find/prevent those bugs, and I'm all for going with
the stricter rules. But you're so far off base with the above argument
that I wonder whether we understand each other at all.

regards, tom lane


From: mark(at)mark(dot)mielke(dot)cc
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Martijn van Oosterhout <kleptog(at)svana(dot)org>, Andrew Dunstan <andrew(at)dunslane(dot)net>, Taral <taralx(at)gmail(dot)com>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: ANSI-strict pointer aliasing rules
Date: 2006-04-27 15:08:59
Message-ID: 20060427150859.GB26734@mark.mielke.cc
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

On Thu, Apr 27, 2006 at 10:49:02AM -0400, Tom Lane wrote:
> mark(at)mark(dot)mielke(dot)cc writes:
> > Even if it was only 1% - 2%. Isn't it worth it? :-)
> No. According to the ancient saying, "I can make this program
> arbitrarily fast ... if it doesn't have to give the right answer".
> Percentage-point improvements are not worth the risk of introducing
> hard-to-find, compiler-and-hardware-dependent bugs.

Addressing the aliasing rule concerns raised by the compiler, at least
in theory, is improving the compatibility of the program, and reducing
the number of bugs that may be exposed under unusual circumstances. If
PostgreSQL isn't alias safe - it means that there is casting
happening, that is not generally accepted as valid, minimizing the
optimization potential of the code, and certainly not guaranteed to be
correct. Every cast in C has the potential to contain bugs today, or
tomorrow when somebody changes the lvalue or rvalue. If the types are
incompatible, according the compiler, the odds of a bug happening today
or tomorrow become greater.

If you are worried about PostgreSQL making use of the optimization
potential - and suggesting that by PostgreSQL making this impossible
currently, that you are preventing a compiler-and-hardware-dependent
bug, I strongly disagree. If most code is compiled with the aliasing
rules enabled in the optimizer, and your code is compiled with the
aliasing rules disabled, then you are using the lesser used
optimization paths in the compiler, actually raising the likelihood of
such a compiler bug being exposed. Compilers do have bugs - and by
choosing to use the non-standard optimization models, the chance of
you finding it first increases. You don't really want to be first.
You want the regression testing of the compiler to be first. :-)

> Show me how to find/prevent those bugs, and I'm all for going with
> the stricter rules. But you're so far off base with the above argument
> that I wonder whether we understand each other at all.

I think we can agree on the intrusiveness of the change needing to
be linear or less to the value of the change. If the fix is simple,
and it generates a 1% - 2% gain - you are buying both performance,
and correctness. Personally, I value correctness. I think some would
value performance though.

We're both playing opposite roles, to lead to a balanced discussion,
which is good. Not off base. Contrary. How could you expect to have
a balanced discussion otherwise? :-)

Cheers,
mark

--
mark(at)mielke(dot)cc / markm(at)ncf(dot)ca / markm(at)nortel(dot)com __________________________
. . _ ._ . . .__ . . ._. .__ . . . .__ | Neighbourhood Coder
|\/| |_| |_| |/ |_ |\/| | |_ | |/ |_ |
| | | | | \ | \ |__ . | | .|. |__ |__ | \ |__ | Ottawa, Ontario, Canada

One ring to rule them all, one ring to find them, one ring to bring them all
and in the darkness bind them...

http://mark.mielke.cc/


From: Martijn van Oosterhout <kleptog(at)svana(dot)org>
To: mark(at)mark(dot)mielke(dot)cc
Cc: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Andrew Dunstan <andrew(at)dunslane(dot)net>, Taral <taralx(at)gmail(dot)com>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: ANSI-strict pointer aliasing rules
Date: 2006-04-27 15:30:14
Message-ID: 20060427153014.GJ29830@svana.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

On Thu, Apr 27, 2006 at 11:08:59AM -0400, mark(at)mark(dot)mielke(dot)cc wrote:
> ... If
> PostgreSQL isn't alias safe - it means that there is casting
> happening, that is not generally accepted as valid, minimizing the
> optimization potential of the code, and certainly not guaranteed to be
> correct. Every cast in C has the potential to contain bugs today, or
> tomorrow when somebody changes the lvalue or rvalue. If the types are
> incompatible, according the compiler, the odds of a bug happening today
> or tomorrow become greater.

You're right, PostgreSQL uses a form of subclassing, so that a (for
example) struct ArrayRefExprState is occasionally referred to using a
(struct ExprState*) or even a (struct Node*). In C, the logical way to
get that to work it by casting, do you have a better way?

The fact is, strict-aliasing only breaks things in the name of
performence.

> I think we can agree on the intrusiveness of the change needing to
> be linear or less to the value of the change. If the fix is simple,
> and it generates a 1% - 2% gain - you are buying both performance,
> and correctness. Personally, I value correctness. I think some would
> value performance though.

The fix is not simple. We wouldn't have disabled it if the fix was
easy. Basically, with strict-aliasing enabled, things break. The
compiler won't identify all the issues for you, how do you know you're
safe? So the system is actually *more* correct with strict-aliasing
disabled, because then it does exactly what the code says...

The two major other places we use casts are converting Datums to their
actual types, and our MemSet which replaces the braindead GCC one.

Have a nice day,
--
Martijn van Oosterhout <kleptog(at)svana(dot)org> http://svana.org/kleptog/
> From each according to his ability. To each according to his ability to litigate.


From: Greg Stark <gsstark(at)mit(dot)edu>
To: Martijn van Oosterhout <kleptog(at)svana(dot)org>
Cc: mark(at)mark(dot)mielke(dot)cc, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>, Andrew Dunstan <andrew(at)dunslane(dot)net>, Taral <taralx(at)gmail(dot)com>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: ANSI-strict pointer aliasing rules
Date: 2006-04-27 16:43:37
Message-ID: 87slnz6kau.fsf@stark.xeocode.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

Martijn van Oosterhout <kleptog(at)svana(dot)org> writes:

> You're right, PostgreSQL uses a form of subclassing, so that a (for
> example) struct ArrayRefExprState is occasionally referred to using a
> (struct ExprState*) or even a (struct Node*). In C, the logical way to
> get that to work it by casting, do you have a better way?

There are other ways of achieving the same thing. Structs containing a union
for the subclass fields for example.

--
greg


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Greg Stark <gsstark(at)mit(dot)edu>
Cc: Martijn van Oosterhout <kleptog(at)svana(dot)org>, mark(at)mark(dot)mielke(dot)cc, Andrew Dunstan <andrew(at)dunslane(dot)net>, Taral <taralx(at)gmail(dot)com>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: ANSI-strict pointer aliasing rules
Date: 2006-04-27 16:50:10
Message-ID: 12187.1146156610@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

Greg Stark <gsstark(at)mit(dot)edu> writes:
> Martijn van Oosterhout <kleptog(at)svana(dot)org> writes:
>> You're right, PostgreSQL uses a form of subclassing, so that a (for
>> example) struct ArrayRefExprState is occasionally referred to using a
>> (struct ExprState*) or even a (struct Node*). In C, the logical way to
>> get that to work it by casting, do you have a better way?

> There are other ways of achieving the same thing. Structs containing a union
> for the subclass fields for example.

Doesn't achieve the same thing, unless you mandate that every part of
the system use the identical massively-overloaded union struct to refer
to every node. That would (a) defeat the purpose of extensibility, and
(b) make the code more error prone not less so (since it'd be
notationally easy to refer to a field that's not actually present in the
given node subtype).

regards, tom lane


From: Taral <taralx(at)gmail(dot)com>
To: pgsql-hackers(at)postgresql(dot)org
Subject: Re: ANSI-strict pointer aliasing rules
Date: 2006-04-27 17:10:31
Message-ID: fa0147d90604271010n3dca44f1t88a05fa39ec274f@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

On 4/27/06, Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> wrote:
> Greg Stark <gsstark(at)mit(dot)edu> writes:
> > There are other ways of achieving the same thing. Structs containing a union
> > for the subclass fields for example.
>
> Doesn't achieve the same thing, unless you mandate that every part of
> the system use the identical massively-overloaded union struct to refer
> to every node.

If we do subclassing like this:

struct Node { ... };
struct Value { struct Node; ... };
etc.

do we still run into the alias problem?

--
Taral <taralx(at)gmail(dot)com>
"You can't prove anything."
-- Gödel's Incompetence Theorem


From: Taral <taralx(at)gmail(dot)com>
To: pgsql-hackers(at)postgresql(dot)org
Subject: Re: ANSI-strict pointer aliasing rules
Date: 2006-04-27 17:21:55
Message-ID: fa0147d90604271021nd8886a3n4de78dd7148143be@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

On 4/27/06, Taral <taralx(at)gmail(dot)com> wrote:
> If we do subclassing like this:
>
> struct Node { ... };
> struct Value { struct Node; ... };
> etc.
>
> do we still run into the alias problem?

Nope, it appears to get rid of the alias problem completely. But it
requires anonymous structure support (C99?) to work without changing
anything other than headers.

As a bonus, if we ever change Node, we don't have to update any other
structures...

--
Taral <taralx(at)gmail(dot)com>
"You can't prove anything."
-- Gödel's Incompetence Theorem


From: Martijn van Oosterhout <kleptog(at)svana(dot)org>
To: Taral <taralx(at)gmail(dot)com>
Cc: pgsql-hackers(at)postgresql(dot)org
Subject: Re: ANSI-strict pointer aliasing rules
Date: 2006-04-27 17:52:54
Message-ID: 20060427175254.GK29830@svana.org
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

On Thu, Apr 27, 2006 at 12:21:55PM -0500, Taral wrote:
> > If we do subclassing like this:
> >
> > struct Node { ... };
> > struct Value { struct Node; ... };
> > etc.
> >
> > do we still run into the alias problem?
>
> Nope, it appears to get rid of the alias problem completely. But it
> requires anonymous structure support (C99?) to work without changing
> anything other than headers.

On that compiler maybe, but what about others? What other problems does
strict-alias cause? Anyway, near as I can tell, anonymous structs are
not in the C standard and I don't think GCC supports them either...

> As a bonus, if we ever change Node, we don't have to update any other
> structures...

Node is unlikely to ever change, it's been like this for at least ten
years...

Have a nice day,
--
Martijn van Oosterhout <kleptog(at)svana(dot)org> http://svana.org/kleptog/
> From each according to his ability. To each according to his ability to litigate.


From: Greg Stark <gsstark(at)mit(dot)edu>
To: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
Cc: Greg Stark <gsstark(at)mit(dot)edu>, Martijn van Oosterhout <kleptog(at)svana(dot)org>, mark(at)mark(dot)mielke(dot)cc, Andrew Dunstan <andrew(at)dunslane(dot)net>, Taral <taralx(at)gmail(dot)com>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: ANSI-strict pointer aliasing rules
Date: 2006-04-27 19:25:45
Message-ID: 87hd4e7rd2.fsf@stark.xeocode.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> writes:

> Greg Stark <gsstark(at)mit(dot)edu> writes:
>
> > There are other ways of achieving the same thing. Structs containing a union
> > for the subclass fields for example.
>
> Doesn't achieve the same thing, unless you mandate that every part of
> the system use the identical massively-overloaded union struct to refer
> to every node.

Are you saying it's important to preserve the ability for modules to add new
node types without notifying the rest of the code? I thought all the node
types were defined in a single header file currently anyways.

> That would (a) defeat the purpose of extensibility, and (b) make the code
> more error prone not less so (since it'd be notationally easy to refer to a
> field that's not actually present in the given node subtype).

You could use a local pointer to be preserve the existing model of a single
point where the decision is made. That could be encapsulated in a macro that
included an assertion to verify the type tag.

It would be pretty cool to have a type-safe codebase. It just seems like too
an awful lot of work for a mostly aesthetic improvement.

--
greg


From: Taral <taralx(at)gmail(dot)com>
To: pgsql-hackers(at)postgresql(dot)org
Subject: Re: ANSI-strict pointer aliasing rules
Date: 2006-04-27 19:42:35
Message-ID: fa0147d90604271242q396eda75xf47b0e9b0128f5cf@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

On 27 Apr 2006 15:25:45 -0400, Greg Stark <gsstark(at)mit(dot)edu> wrote:
> It would be pretty cool to have a type-safe codebase. It just seems like too
> an awful lot of work for a mostly aesthetic improvement.

Does anyone have some benchmarks I can run? I can run tests to see if
this aliasing makes a noticeable difference or not...

--
Taral <taralx(at)gmail(dot)com>
"You can't prove anything."
-- Gödel's Incompetence Theorem


From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: Greg Stark <gsstark(at)mit(dot)edu>
Cc: Martijn van Oosterhout <kleptog(at)svana(dot)org>, mark(at)mark(dot)mielke(dot)cc, Andrew Dunstan <andrew(at)dunslane(dot)net>, Taral <taralx(at)gmail(dot)com>, pgsql-hackers(at)postgresql(dot)org
Subject: Re: ANSI-strict pointer aliasing rules
Date: 2006-04-27 19:56:30
Message-ID: 15068.1146167790@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

Greg Stark <gsstark(at)mit(dot)edu> writes:
> Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us> writes:
>> Doesn't achieve the same thing, unless you mandate that every part of
>> the system use the identical massively-overloaded union struct to refer
>> to every node.

> Are you saying it's important to preserve the ability for modules to add new
> node types without notifying the rest of the code? I thought all the node
> types were defined in a single header file currently anyways.

No, they're scattered through at least half a dozen headers. We don't
really have "dynamic" extensibility because the NodeTag enum is declared
in just one place, but we do have separation of concerns: stuff dealing
with parsenodes.h need not import all the executor node types, for
instance. The big objection to a single-union-struct approach is that
it forecloses any locality of knowledge about node types.

(I also wonder how many compilers would give up the ghost entirely on
being fed a union type of 250+ separate structs, with in aggregate
several thousand fields ... and even if they didn't fail, how fast
they'd compile code making heavy use of such a beast.)

> It would be pretty cool to have a type-safe codebase. It just seems like too
> an awful lot of work for a mostly aesthetic improvement.

Yeah, I think that's how we all feel. I'd not even waste any time
thinking about it, except that I'm afraid the compiler guys may
eventually stop supporting the traditional semantics ...

regards, tom lane


From: mark(at)mark(dot)mielke(dot)cc
To: Taral <taralx(at)gmail(dot)com>
Cc: pgsql-hackers(at)postgresql(dot)org
Subject: Re: ANSI-strict pointer aliasing rules
Date: 2006-04-27 21:20:57
Message-ID: 20060427212057.GA30594@mark.mielke.cc
Views: Raw Message | Whole Thread | Download mbox | Resend email
Lists: pgsql-hackers

On Thu, Apr 27, 2006 at 02:42:35PM -0500, Taral wrote:
> On 27 Apr 2006 15:25:45 -0400, Greg Stark <gsstark(at)mit(dot)edu> wrote:
> > It would be pretty cool to have a type-safe codebase. It just seems like
> > too an awful lot of work for a mostly aesthetic improvement.

> Does anyone have some benchmarks I can run? I can run tests to see if
> this aliasing makes a noticeable difference or not...

You would have to fix the code first. :-)

I completely back down when it comes down to the suspected
intrusiveness of the change, causing too much upset. It's the idea
that the aliasing rules are not worth following, that caused me to
enter. Until a good patch is available, that is less intrusive than
what people are suspecting, nothing is going to change.

I suspect a patch to convert PostgreSQL to C++ wouldn't be
welcomed. Haha...

Cheers,
mark

--
mark(at)mielke(dot)cc / markm(at)ncf(dot)ca / markm(at)nortel(dot)com __________________________
. . _ ._ . . .__ . . ._. .__ . . . .__ | Neighbourhood Coder
|\/| |_| |_| |/ |_ |\/| | |_ | |/ |_ |
| | | | | \ | \ |__ . | | .|. |__ |__ | \ |__ | Ottawa, Ontario, Canada

One ring to rule them all, one ring to find them, one ring to bring them all
and in the darkness bind them...

http://mark.mielke.cc/