You are not logged in.
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
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
I wondered what you would all think of the code :shock: 8) 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
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
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
...
That should work....
I think you're going to need to increment p somewhere in there.
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