Skip to content

Commit

Permalink
Fix handling of integer preference parameters
Browse files Browse the repository at this point in the history
Before this commit, the code did:
    int max = G_MAXINT; /* INT_MAX, 2147483647 */
    float factor = 1.0f;
    max *= factor;

Dimitry Andric helped me understand the problem; here is the
explanation:
    Here, "max * factor" is 2147483648.0, not 2147483647.0: the value is
    rounded up because the float type has a mantissa of 23 bits only.
    However, converting 2147483648.0 to an integer is an undefined
    behaviour.

The resulting value depends on the compiler and the level of
optimization:

    GCC (all versions) with -O0: max = -2147483648
    GCC (all versions) with -O2: max =  2147483647

    Clang up-to 3.5 with -O0:    max = -2147483648
    Clang up-to 3.5 with -O2:    max =  2147483647
    (ie. same behaviour as GCC)

    Clang 3.6+ with -O0:         max = -2147483648
    Clang 3.6+ with -O2:         max =           0

In the context of the preferences dialog, this means that all integers
must be between min=0 and max=0.

The fix, suggested by Dimitry, is to use a double as an intermediate
variable: it is wide enough to store "max * factor" without rounding up
the value. Then, 2147483647.0 can be converted to 2147483647.

(cherry picked from commit 9d77a28)
  • Loading branch information
dumbbell authored and pmjdebruijn committed Apr 18, 2015
1 parent 6bc644e commit c59e18c
Showing 1 changed file with 3 additions and 1 deletion.
4 changes: 3 additions & 1 deletion tools/generate_prefs.xsl
Original file line number Diff line number Diff line change
Expand Up @@ -231,7 +231,9 @@
<xsl:text> gint min = 0;&#xA; gint max = G_MAXINT;&#xA;</xsl:text>
<xsl:apply-templates select="type" mode="range"/>
<xsl:text> </xsl:text><xsl:apply-templates select="type" mode="factor"/>
<xsl:text> min *= factor; max *= factor;
<xsl:text> double tmp;
tmp = min * (double)factor; min = tmp;
tmp = max * (double)factor; max = tmp;
widget = gtk_spin_button_new_with_range(min, max, 1);
gtk_spin_button_set_digits(GTK_SPIN_BUTTON(widget), 0);
gtk_spin_button_set_value(GTK_SPIN_BUTTON(widget), dt_conf_get_int("</xsl:text><xsl:value-of select="name"/><xsl:text>") * factor);
Expand Down

0 comments on commit c59e18c

Please sign in to comment.