You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@stdcxx.apache.org by se...@apache.org on 2006/07/31 23:24:11 UTC
svn commit: r427285 - /incubator/stdcxx/trunk/etc/config/src/LIMITS.cpp
Author: sebor
Date: Mon Jul 31 14:24:11 2006
New Revision: 427285
URL: http://svn.apache.org/viewvc?rev=427285&view=rev
Log:
2006-07-31 Martin Sebor <se...@roguewave.com>
STDCXX-264
* LIMITS.cpp (compute_min): Renamed from foo.
(greater): Removed.
(compute_limits): Used the volatile globals zero, one, and two
instead the locals to (try to) foil aggressive optimizers and
avoid undefined behavior due to signed overflow. Used said
globals instead of integer constants consistently in all
arithmetic expressions.
Modified:
incubator/stdcxx/trunk/etc/config/src/LIMITS.cpp
Modified: incubator/stdcxx/trunk/etc/config/src/LIMITS.cpp
URL: http://svn.apache.org/viewvc/incubator/stdcxx/trunk/etc/config/src/LIMITS.cpp?rev=427285&r1=427284&r2=427285&view=diff
==============================================================================
--- incubator/stdcxx/trunk/etc/config/src/LIMITS.cpp (original)
+++ incubator/stdcxx/trunk/etc/config/src/LIMITS.cpp Mon Jul 31 14:24:11 2006
@@ -46,6 +46,13 @@
// set to 1 if this is not a two's complement architecture
int no_twos_complement = 0;
+// volatile to foil aggressive optimizers
+volatile int zero = 0;
+volatile int one = zero + 1;
+volatile int two = one + 1;
+volatile int zero_complement = ~zero;
+
+
template<class T>
void print_limit (T n, const char *pfx, const char *sfx,
@@ -117,12 +124,12 @@
template <class T>
-T foo (T one, T min)
+T compute_min (T min)
{
// prevents overzealous gcc optimizer from invoking
// undefined behavior on signed integer over/underflow
for (T tmp; ; --min) {
- tmp = min - one;
+ tmp = T (min - one);
if (tmp >= min)
break;
}
@@ -130,14 +137,6 @@
return min;
}
-template <class T>
-T greater (T lhs, T rhs)
-{
- // prevents overzealous gcc optimizer from invoking
- // undefined behavior on signed integer over/underflow
- return lhs > rhs;
-}
-
template <class T>
const char* type_suffix (T) { return ""; }
@@ -163,23 +162,22 @@
template <class T>
T compute_limits (T, const char *pfx, const char *sfx, const char *type)
{
- T zero = T (0);
- T min = T (-1);
- T max = T (1);
- T one = T (1);
+ T min = T (-one);
+ T max = T (one);
- int is_signed = T (min - T (1)) < zero;
+ int is_signed = T (min - one) < T (zero);
if (!is_signed)
max = min;
- for (; T (max * 2) > max; max *= 2);
- for (T n = max / 4; n; ) {
+ // compute the maximum representable value
+ for (; T (max * two) > max; max *= two);
+ for (T n = max / (two + two); n; ) {
if (T (max + n) < max) {
- if (n > 2)
- n /= 2;
- else if (greater (T (max + one), max))
- n = 1;
+ if (n > T (two))
+ n /= two;
+ else if (max < T (max + one))
+ n = one;
else
break;
}
@@ -187,19 +185,18 @@
max += n;
}
+ // print the maximum representable value
print_limit (max, pfx, sfx, true, type);
- min = -max;
-
- // compute a minimum
- for (; T (min * 2) < min; min *= 2);
+ // compute the minimum representable value
+ for (min = -max; T (min * two) < min; min *= two);
// working around a gcc optimizer "feature" (PR #26211)
// signed integer overflow is undefined behavior
// for (; T (min - 1) < min; min -= 1);
- min = foo (one, min);
+ min = compute_min (min);
- print_limit<T> (min, pfx, sfx, false, type);
+ print_limit (min, pfx, sfx, false, type);
return max;
}
@@ -223,12 +220,6 @@
// to silence printf() format comaptibility warnings
#define SIZEOF(T) unsigned (sizeof (T))
-
-
-volatile int zero = 0;
-volatile int one = zero + 1;
-volatile int two = one + 1;
-volatile int zero_complement = ~zero;
int main ()