Re: Reliance on undefined behaviour in << operator

From: Kyotaro HORIGUCHI <horiguchi(dot)kyotaro(at)lab(dot)ntt(dot)co(dot)jp>
To:
Cc: pgsql-hackers(at)postgresql(dot)org
Subject: Re: Reliance on undefined behaviour in << operator
Date: 2015-09-16 08:33:28
Message-ID: 20150916.173328.194431111.horiguchi.kyotaro@lab.ntt.co.jp
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

Hello, I don't think so many people have used shift operators
with too-large or negative shift amount relying on the
undetermined behavior.

But if explicit definition is required, I prefer the result of a
shift operation with too-large shift mount is simplly zero. And
shift left with negative shift amount should do right
shift. Addition to that, no error nor warning won't be needed.

Like this,

Datum
int8shl(PG_FUNCTION_ARGS)
{
int64 arg1 = PG_GETARG_INT64(0);
int32 arg2 = PG_GETARG_INT32(1);

if (arg2 > 63 || arg2 < -63) PG_RETURN_INT64(0L);
if (arg2 < 0)
PG_RETURN_INT64(arg1 >> (-arg2));

PG_RETURN_INT64(arg1 << arg2);
}

The obvious problem on this is the lack of compatibility with
existing behavior:(

Thoughts? Opinions?

regards,

At Wed, 16 Sep 2015 15:16:27 +0800, Craig Ringer <craig(at)2ndquadrant(dot)com> wrote in <CAMsr+YE+0KJuOJfbB2nLVfU+14R50Yi90e_8DewLV9jX+ro1zg(at)mail(dot)gmail(dot)com>
> Hi all
>
> Our implementation of << is a direct wrapper around the C operator. It
> does not check the right-hand side's value.
>
>
> Datum
> int8shl(PG_FUNCTION_ARGS)
> {
> int64 arg1 = PG_GETARG_INT64(0);
> int32 arg2 = PG_GETARG_INT32(1);
>
> PG_RETURN_INT64(arg1 << arg2);
> }
>
> This means that an operation like:
>
> 1::bigint << 65
>
> directly relies on the compiler and platforms' handling of the
> undefined shift. On x64 intel gcc linux it does a rotation but that's
> not AFAIK guaranteed by anything, and we should probably not be
> relying on this or exposing it at the user level.
>
>
>
> Pg returns:
>
> test=> SELECT BIGINT '1' << 66;
> ?column?
> ----------
> 4
> (1 row)
>
> A test program:
>
> #include "stdio.h"
> int main(int argc, char * argv[])
> {
> printf("Result is %ld", 1l << 66);
> return 0;
> }
>
> returns zero when the compiler constant-folds, but when done at runtime:
>
> #include <stdio.h>
> #include <stdlib.h>
> int main(int argc, char * argv[])
> {
> const char * num = "66";
> printf("Result is %ld", 1l << atoi(num));
> return 0;
> }
>
>
> IMO we should specify the behaviour in this case. Then issue a WARNING
> that gets promoted to an ERROR in a few versions.
>
> Consideration of << with a negative right-operand, and of
> out-of-bounds >>, is probably also needed.
>
> Thoughts?

--
Kyotaro Horiguchi
NTT Open Source Software Center

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Daniel Verite 2015-09-16 09:35:08 Re: [patch] Proposal for \rotate in psql
Previous Message Dean Rasheed 2015-09-16 07:31:37 Inaccurate results from numeric ln(), log(), exp() and pow()