Bug 33248 - The execution gives wrong results when compiled with mingw32-gcc 3.4.2
Summary: The execution gives wrong results when compiled with mingw32-gcc 3.4.2
Status: RESOLVED DUPLICATE of bug 11751
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 3.4.2
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2007-08-30 12:12 UTC by Alain Ducasse
Modified: 2007-08-30 16:10 UTC (History)
56 users (show)

See Also:
Host: xp sp1
Target: win32
Build: mingw32-gcc 3.4.2 / MinGW-5.1.3
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Alain Ducasse 2007-08-30 12:12:15 UTC
source file :

/*
 * The execution gives wrong results when compiled with mingw32-gcc 3.4.2
 * (MinGW-5.1.3)
 * (no problem with previous mingw32-gcc 3.2.3 / MinGW-3.1.0)
 *
 *   KO when REAL = float
 *   OK when REAL = double
 *
 *   Expected results are : tab[0] = 123 and tab[1] = -123
 *
 *   If instead of 
 *
 *     *p++ = (REAL) floor((double) *p + 0.5);
 *     *p++ = (REAL) floor((double) *p + 0.5);
 *
 *   code is
 *
 *     *p = (REAL) floor((double) *p + 0.5);
 *     p++;
 *     *p = (REAL) floor((double) *p + 0.5);
 *     p++;
 *
 *   the execution is OK.
 */

#include <stdlib.h>
#include <stdio.h>
#include <math.h>

#define REAL  float  /* comment for use 'double' */

#ifndef REAL
#define REAL  double
#endif


int main()
{
  REAL  tab[2],*p;

  tab[0] =  123.456;
  tab[1] = -123.456;

  p = &tab[0];

  *p++ = (REAL) floor((double) *p + 0.5);
  *p++ = (REAL) floor((double) *p + 0.5);

  fprintf(stdout,">>> tab[0] = %f, tab[1] = %f\n",
                 (double) tab[0],(double) tab[1]);
	
  return 0;
}
Comment 1 Richard Biener 2007-08-30 12:33:49 UTC
There is no sequence point between *p++ and *p. So you hit #2 of the most frequently reported (non-)bugs.

*** This bug has been marked as a duplicate of 11751 ***
Comment 2 Alain Ducasse 2007-08-30 15:22:36 UTC
I do not think it is the same bug 11751.

For example:

  *p++ = *p + 1.0;
  *p++ = *p + 1.0;

works. But

  *p++ = (float) floor((double) *p + 0.5);
  *p++ = (float) floor((double) *p + 0.5);

does not work (with float). It is not only the ++ operator that cause the problem.
Why when it is compiled with gcc 3.2.3 there is no problem ?
Why the equivalent code

  *p = (float) floor((double) *p + 0.5);
  p++;
  *p = (float) floor((double) *p + 0.5);
  p++;

works ?
I do not understand "no sequence point between *p++ and *p" ?
Comment 3 Andreas Schwab 2007-08-30 16:10:21 UTC
It invokes undefined behaviour, if it breaks you get to keep the pieces.  There is no requirement that you get any useful result.

http://c-faq.com/expr/evalorder1.html

*** This bug has been marked as a duplicate of 11751 ***