From: ThosRTanner on 12 Aug 2010 03:13 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 12 Aug 2010 23:21 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 13 Aug 2010 03:39 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 |