Pelles C forum

Pelles C => Bug reports => Topic started by: neo313 on June 22, 2013, 08:29:32 PM

Title: Bug using an global array of structs, overwriting variables
Post 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:

Code: [Select]
#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

Title: Re: Bug using an global array of structs, overwriting variables
Post by: JohnF on June 22, 2013, 09:36:57 PM
The bug goes away with no optimizations.

John
Title: Re: Bug using an global array of structs, overwriting variables
Post by: neo313 on June 22, 2013, 09:44:15 PM
The bug goes away with no optimizations.

John

Indeed it does, so it is a pelles bug;
i forgot to check for optimizations
Title: Re: Bug using an global array of structs, overwriting variables
Post by: neo313 on June 22, 2013, 10:29:00 PM
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
Title: Re: Bug using an global array of structs, overwriting variables
Post by: TimoVJL on June 23, 2013, 08:22:25 AM
Seems to zeroing whole struct:
Code: [Select]
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
Title: Re: Bug using an global array of structs, overwriting variables
Post by: frankie on June 23, 2013, 01:33:46 PM
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:
Code: [Select]
#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:
Code: [Select]
#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  :'(
Title: Re: Bug using an global array of structs, overwriting variables
Post by: neo313 on June 23, 2013, 08:28:08 PM
Is there any chance that this bug will get fixed, or in other words is pelles still being supported by the author?
Title: Re: Bug using an global array of structs, overwriting variables
Post by: frankie on June 24, 2013, 11:37:32 AM
As far as we know he is still supporting even if we don't have any date for updates.