From: ThosRTanner on
I've seen one compiler where this:

int32_t get_val(char const *s, std::size_t len, uint8_t base)
{
bool is_neg;
// set isneg
int32_t min = std::numeric_limits<int32_t>::min();
int32_t max = std::numeric_limits<int32_t>::max();
int32_t lim = isneg ? (-(min / base)) : (max / base);
//blah
}

Now on one compiler, when you switch on optimisation, the last line
appears to be evaluated as:
int32_t lim = (isneg ? -min : max) / base;

which doesn't work, as -min is still negative, and lim gets a negative
result, whereas it should be positive.

So - is this a valid optimisation or not? I thought only negating the
most negative integer was undefined.

--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Bart van Ingen Schenau on
On Aug 12, 8:13 pm, ThosRTanner <ttann...(a)bloomberg.net> wrote:
> I've seen one compiler where this:
>
> int32_t get_val(char const *s, std::size_t len, uint8_t base)
> {
> bool is_neg;
> // set isneg
> int32_t min = std::numeric_limits<int32_t>::min();
> int32_t max = std::numeric_limits<int32_t>::max();
> int32_t lim = isneg ? (-(min / base)) : (max / base);
> //blah
>
> }
>
> Now on one compiler, when you switch on optimisation, the last line
> appears to be evaluated as:
> int32_t lim = (isneg ? -min : max) / base;
>
> which doesn't work, as -min is still negative, and lim gets a negative
> result, whereas it should be positive.
>
> So - is this a valid optimisation or not? I thought only negating the
> most negative integer was undefined.

For this particular case, the optimisation is not valid. My guess is
that the compiler does not take this corner-case into account when
applying the optimisation.

Negating a value is only UB if the result can not be represented. This
is only the case when the implementation uses 2-s complement
representation for negative integers and you try to negate the most
negative value.

Bart v Ingen Schenau


--
[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

From: Jens Schmidt on
ThosRTanner wrote:

> I've seen one compiler where this:
>
> int32_t get_val(char const *s, std::size_t len, uint8_t base)
> {
> bool is_neg;
> // set isneg
> int32_t min = std::numeric_limits<int32_t>::min();
> int32_t max = std::numeric_limits<int32_t>::max();
> int32_t lim = isneg ? (-(min / base)) : (max / base);
> //blah
> }
>
> Now on one compiler, when you switch on optimisation, the last line
> appears to be evaluated as:
> int32_t lim = (isneg ? -min : max) / base;

Source code as an intermediate format for optimisation is very unusual.
How did you get that line? Re-sourcing an assembly listing? A guess
from debugging?

> which doesn't work, as -min is still negative, and lim gets a negative
> result, whereas it should be positive.
>
> So - is this a valid optimisation or not?

It is not. A valid optimisation is one where the actual hardware produces
the same result as the abstract machine for all defined cases.

> I thought only negating the most negative integer was undefined.

I don't understand, what 'only' means in this context. There are a lot of
undefined cases, most of them not having to do with negating. Let's suppose
you meant 'Negating integers is undefined only for the most negative value.'
As Bart already answered, this depends on the representation. Also, the
compiler knows a lot more about the target machine than the C++ standard.
It may use this knowledge of how the target machine works even in cases
where the standard defines no specific behaviour. The very similar line
int32_t lim
= static_cast<int32_t>((isneg ? static_cast<uint32_t>(-min)
: static_cast<uint32_t>(max)) / base);
still invokes undefined behaviour in C++, but most (the compiler might know:
the one that is currently the target) processors will produce the correct
result, because static_cast between int32_t and uint32_t is often the same
as reinterpret_cast. The only difference is an unsigned division versus a
signed one.
--
Greetings,
Jens Schmidt


[ See http://www.gotw.ca/resources/clcm.htm for info about ]
[ comp.lang.c++.moderated. First time posters: Do this! ]

 | 
Pages: 1
Prev: Output Generated From Templates