|
|||
|
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> ram@zedat.fu-berlin.de (Stefan Ram) writes: > >> ram@zedat.fu-berlin.de (Stefan Ram) writes: >>>void rstrip( char * const string ) >>>{ char * p = string + strlen( string ); >>> while( p-- > string && isspace( p ))*p = 0; } > > Both here and below you meant to write isspace(*p). > >> or, more careful: >> >> void rstrip( char * const string ) >> { char * p = string + strlen( string ); if( p > string ) >> while( p-- > string && isspace( p ))*p = 0; } > > No, that has a similar problem. Unfortunately you've cut the context so > it won't be clear what you were correcting. The problem was > constructing an invalid pointer that points before the start of the > string and this code can also do that when the string is all spaces. > > In addition to being careful about the pointers, you need to finesse the > mess that is isspace (and friends) when char might be signed. It's a > shame that what should be a simple function is really quite tricky. My solution had two statements and one single-line macro definition. > char *rstrip(unsigned char *string) > { > char *ep = strchr(0); > while (ep > string && isspace(ep[-1])) --ep; > *ep = 0; > return string; > } > > (The unsigned char * just is to avoid cluttering the code with a cast I think you've got your unsigned-ness in the wrong place. > or Tim's exotic compound literal union.) Exotic?!??? Why that's ridiculous. ![]() More seriously, this sort of thing should be bundled up in a macro definition, and with C11 now coming to the fore, a macro around a _Generic expression should work quite nicely. |
|
|
||||
|
||||
|
|
|
|||
|
>>> p=str+length-1;
>>> >>> while (p>=str && *p-- == ' ') --length; > OK, let's suppose that on some machine, it is meaningless to point to an > address before 'str'; why would the problem occur on the next access to p, > rather than in the p-- operation, or in the >= comparison? It might occur on p--;. Some processors (Pentium included, if you use the right pointer types, which would be associated with large memory model (48-bit pointers)) will trap if you load an invalid pointer into a segment register. Programs that need 48-bit pointers are *big* programs. However, this kind of pickiness tends to break supposedly working software and it will be unpopular with customers. Also, it isn't necessary to put a pointer into a segment register just for this and putting a pointer into a segment register is an expensive operation on a Pentium. C is not guaranteed to catch such errors (you might read random crap instead of trapping) and it is especially not guaranteed to catch such errors as soon as possible. > And, on a machine which doesn't have such problems (eg. flat address space, > str not located at the beginning of that space, and the ability to compare > pointers even when the memory locations involved do not exist), would it > still be undefined behaviour? Regardless of what it *DOES*, it's still undefined behavior: there is no wrong behaviour. One of the most insidious forms of undefined behavior is "do what I expected" or "do what I expected except under conditions only likely to happen during a demonstration of the software to the customer". Some systems randomize the locations of where things are loaded to avoid vulnerabilities to things such as buffer-overflow attacks (it might still crash but not be an exploitable hole for a virus to take over the computer), so it might actually end up at the beginning of the space 0.01% of the time. |
|
|||
|
> Regardless of what it *DOES*, it's still undefined behavior: there
> is no wrong behaviour. One of the most insidious forms of undefined > behavior is "do what I expected" or "do what I expected except under The suggested pseudo-code was n := strlen(s) while n>0 and isspace(s[n-1]), s[--n] := 0 where you use an integer subscript instead of a pointer. The integer can go out of range as long as it is guarded so the subscript is always in range. If n=0, the subscripts s[n-1] and s[--n] would be invalid, but the guard n>0 keeps them from being evaluated. -- My name Indigo Montoya. | R'lyeh 38o57'6.5''S 102o51'16''E. You flamed my father. | I'm whoever you want me to be. Prepare to be spanked. | Annoying Usenet one post at a time. Stop posting that! | At least I can stay in character. |
|
|
![]() |
| Thread Tools | |
| Display Modes | |
|
|