You are not logged in.

#1 2005-10-20 02:55:53

cs25x
Member
Registered: 2004-05-04
Posts: 150

gcc 4.0.3 20051006 optimization breaks my code

or else I miss something. This has worked since January and it broke when I moved to gcc4. Here in brief

void foo(char *tsp)
{
 while(*tsp != NULL)
 {
  if((*tsp == ' ') & ((*(++tsp) == ' ')) --(*(tsp-1));
 }
// then scan for < ' ' and we have eliminated multiple blanks
}

That section checks for multiple blanks in a string of text, and it decrements any multiple blank chars, so they become unprintable. Then futher down, I copy the line, skipping anything which is less than a blank. So far so good. The single '&' guarentees that tsp will be incremented, and it should be incremented before it is used. The output

A B  C D

should look like this:

A B C D

but it looks like this

@ A B C

This indicates tsp is being incremented AFTER it is being used or something else strange is happening in the test.
I did a test with gcc -S, and the code it puts out looks to be correct, but when I switch on optimization, it is most certainly wrong. I was using O6, but  it even barfs with just a plain gcc -S -O foo.c  After I removed optimization from the Makefile, it works as it did before with gcc 3.x.


--(*(cs25x--));

Offline

#2 2005-10-20 03:35:16

Cerebral
Forum Fellow
From: Waterloo, ON, CA
Registered: 2005-04-08
Posts: 3,108
Website

Re: gcc 4.0.3 20051006 optimization breaks my code

Wow.. that's some pretty crazy code to remove multiple spaces.  Maybe try this?

void strip_multiple_blanks(char *tmp) 
{
    char *p = NULL;

    /* Iterate through the whole string */
    for (p=tmp; *p != ''; p++)
    {
        /* If we have at least two spaces in a row...*/
        if (*p == ' ' && *(p+1) == ' ')
        {
            /* Make sure we skip over all the spaces. */
            while( *(++p) == ' ');
            p--;
        }

        /* Copy the character. */
        *tmp = *p;
        tmp++;
    }

    /* Ensure the final string is properly null-terminated. */
    *tmp = '';
}

Offline

#3 2005-10-20 04:02:39

cs25x
Member
Registered: 2004-05-04
Posts: 150

Re: gcc 4.0.3 20051006 optimization breaks my code

I wondered what you would all think of the code :shock:  8)  lol Yes, I will try something different. However, as far as I can tell, optimization breaks on that single line test of mine which has worked without fail on all input, every day since Jan 9, according to the timestamp in the code. I could also simply leave the O switches out of the makefile, because we are only talking about handfull of nanoseconds, and without them ( the switches ) it works perfectly on a test of about 300k lines.


--(*(cs25x--));

Offline

#4 2005-10-20 06:42:58

phrakture
Arch Overlord
From: behind you
Registered: 2003-10-29
Posts: 7,879
Website

Re: gcc 4.0.3 20051006 optimization breaks my code

First off, gcc4 is more strict about following rules, if something broke and it's not warned (did you try -Wall?) then it must be rather subtle.  Why not unobfuscate your code?

void foo(char *tsp)
{
 while(*tsp != NULL)
 {
  if((*tsp == ' ') & ((*(++tsp) == ' ')) --(*(tsp-1));
 }
// then scan for < ' ' and we have eliminated multiple blanks
}

Ummm, you should probably copy the pointer for one, and not mess with passed in value - it's messy.  Also, why mess with this derference+inc/dec stuff?  It's just messy and makes it harder to read.  Also, you have a bitwise AND, not a logical AND.

void foo(const char* tsp)
{
   char* p = tsp;
   while(*p != NULL)
   {
      char* n = p+1;
      if((*p == ' ') && (*n == ' '))
         *p -= 1;
   }
   // then scan for < ' ' and we have eliminated multiple blanks
}

That should work.... but I may be using some C++ specific semantics in there - i run into those from time to time

Offline

#5 2005-10-20 07:10:30

cs25x
Member
Registered: 2004-05-04
Posts: 150

Re: gcc 4.0.3 20051006 optimization breaks my code

phracture, you are close. Yes i always use -Wall, and I did copy the pointer but i only gave a bare outline of code which I tested with and without -O to be certain that the problem remained for anybody who wanted to try. The problem is that the c language test ((A) & (B)) does not specify the order of evaluation of A,B If I used &&, then order is maintained. I fixed it

 if((*(tsp++) == ' ') &&(*tsp == ' '))

unobfuscate?? that is the way I think. This stuff was written in perl 5 years ago. This c code is 100% clear compared to perl. I like your code, it is close to what the compiler does with mine, so I think I will change things. Thanks for your post. 8)


--(*(cs25x--));

Offline

#6 2005-10-20 12:24:30

Cerebral
Forum Fellow
From: Waterloo, ON, CA
Registered: 2005-04-08
Posts: 3,108
Website

Re: gcc 4.0.3 20051006 optimization breaks my code

phrakture wrote:

...
That should work....

I think you're going to need to increment p somewhere in there. tongue

void foo(const char* tsp)
{
   char* p = tsp;
   while(*p != NULL)
   {
      char* n = p+1;
      if((*p == ' ') && (*n == ' '))
         *p -= 1;
      p++;
   }
   // then scan for < ' ' and we have eliminated multiple blanks
}

Offline

Board footer

Powered by FluxBB