Pelles C forum
Pelles C => Bug reports => Topic started by: neo313 on June 22, 2013, 08:29:32 PM
-
When using a global array of structs i have identified the following bug:
1. The struct has two members of any kind
2. when you assing a value to the first member the second member gets overwritten, in fact the next 4 bytes get overwritten
so if you have 4 chars they all get overwritten
3.This only happens if you have a global array struct defined out of scope
4. If the array is of size 1 the bug does not appear, size must be 2 or more
My sscce:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
struct test_s
{
float val ;
int bol ;
} ;
#define LEN 5
struct test_s mystr[LEN] ;
int main( void )
{
for( int i = 0 ; i < LEN ; i += 1 )
{
mystr[i].val = 321.0f ;
mystr[i].bol = 1 ;
}
for( int i = 0 ; i < LEN ; i += 1 )
printf( "\n %f %d" , mystr[i].val , mystr[i].bol ) ;
for( int i = 0 ; i < LEN ; i += 1 )
mystr[i].val = 0.0f ; //set only val to 0
for( int i = 0 ; i < LEN ; i += 1 )
printf( "\n %f %d" , mystr[i].val , mystr[i].bol ) ; //both values get printed as 0, WRONG!
return 0;
}
Output should be http://ideone.com/qWpKPF
321.000000 1
321.000000 1
321.000000 1
321.000000 1
321.000000 1
0.000000 1
0.000000 1
0.000000 1
0.000000 1
0.000000 1
but is
321.000000 1
321.000000 1
321.000000 1
321.000000 1
321.000000 1
0.000000 0
0.000000 0
0.000000 0
0.000000 0
0.000000 0
Can someone please verify this on their version of Pelles IDE.
MY system: Windows 7 32 bit Professional, Service Pack 1 ( Build 7601 ), Pelles Version 7.00.355
-
The bug goes away with no optimizations.
John
-
The bug goes away with no optimizations.
John
Indeed it does, so it is a pelles bug;
i forgot to check for optimizations
-
Minor update:
If I switch the variable position in struct test_s this i get this output: (with optimizations of course)
321.000000 1
321.000000 1
321.000000 1
321.000000 1
321.000000 1
0.000000 1
0.000000 0
0.000000 0
0.000000 0
0.000000 0
-
Seems to zeroing whole struct:
for( int i = 0 ; i < LEN ; i += 1 )
mystr[i].val = 0.0f ; //set only val to 0
[0040104F] BFC4904000 mov edi,mystr
[00401054] 31C0 xor eax,eax
[00401056] B928000000 mov ecx,28
[0040105B] F3AA rep stosb
[0040105D] 31DB xor ebx,ebx
-
The bug comes from static values optimizations, infact if you move your code in a function and pass as parameters the initialization values the compiler doesn.t overwrite struct:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
struct test_s
{
float val ;
int bol ;
} ;
#define LEN 5
struct test_s mystr[LEN] ;
void test(float a, float b)
{
for( int i = 0 ; i < LEN ; i += 1 )
{
//mystr[i].val = 321.0f ;
mystr[i].val = a ;
mystr[i].bol = 1 ;
}
for( int i = 0 ; i < LEN ; i += 1 )
printf( "\n %f %d" , mystr[i].val , mystr[i].bol ) ;
for( int i = 0 ; i < LEN ; i += 1 )
//mystr[i].val = 0.1f ; //set only val to 0
mystr[i].val = b ; //set only val to 0
for( int i = 0 ; i < LEN ; i += 1 )
printf( "\n %f %d" , mystr[i].val , mystr[i].bol ) ; //both values get printed as 0, WRONG!
}
int main( void )
{
test(321.0f, 0.0f);
return 0;
}
Below I report a code piece from my FtypeLib where something similiar happens:
#pragma optimize(none)
/*+@@fnc@@----------------------------------------------------------------*//*!
\brief DynStrFmtAppend
\date Created on Wed Apr 10 22:05:13 2013
\date Modified on Wed Apr 10 22:05:13 2013
\*//*-@@fnc@@----------------------------------------------------------------*/
_FMT_2_3 LPDYNSTR __cdecl DynStrFmtAppend (LPDYNSTR *dynstr, DWORD *cChr, const WCHAR *Fmt, ...)
{
int cLen = 0;
va_list ap;
va_start(ap, Fmt);
cLen = vFmtStrTextLen(Fmt, ap) + 1;
if (cChr)
*cChr = cLen;
if (!dynstr)
return NULL;
_LPDYNSTR p = GETDYNSTRPTR(*dynstr);
if (!p)
return NULL;
p = ResizeDynStr(p, cLen);
if (!p)
{
*dynstr = NULL;
return NULL;
}
vswprintf((p->str)+wcslen(p->str), cLen, Fmt, ap);
va_end(ap);
*dynstr = GETDYNSTRSTR(p);
/*
* COMPILER BUG REPORT.
* When optimizations are on the following line reports always the former string length!
* That's why the compiler makes 2 wrong assumptions:
* 1. That nobody modified the string from the previous 'wcslen' calculation.
* But 'vswprintf' does.
* 2. That the register 'edi', holding the former wcslen(p->str), has not been
* changed before reuse.
*/
p->len = wcslen(p->str) + 1;
return GETDYNSTRSTR(p);
}
#pragma optimize()
Yes advanced optimizations have some bugs :'(
-
Is there any chance that this bug will get fixed, or in other words is pelles still being supported by the author?
-
As far as we know he is still supporting even if we don't have any date for updates.