Yet to mention: I didn't include a NULL-pointer check :D
tux4life
Nearly a Posting Maven
2,350 posts since Feb 2009
Reputation Points: 2,134
Solved Threads: 243
>>return *(--s1) - *(--s2);
That may give you the wrong result. It should be return *s1 - *s2; There are four possible return values If *s1 is '\0' and *s2 is not, then the return value will be some negative value.
If *s1 is NOT '\0' but s2 is, then the return value will be some positive value
If both *s1 and *s2 are '\0' then the return result will be 0.
If neither *s1 nor *s2 is '\0' then the return value could be either positive or negative, depending on their values.
In either event, decrementing s1 and s2 before the subtraction may (and most probably will) produce the wrong result because s1 and s2 will not be pointer to the characters that cause the previous loop to terminate.
Ancient Dragon
Retired & Loving It
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343
@Ancient Dragon:
Thanks for pointing out this issue, I didn't notice it when I was writing the code. However, the solution you suggest (unfortunately) won't fix the problem, since it will create another one.
If I replace return *(--s1) - *(--s2); by return *s1 - *s2; ,
then strcmp("a", "b") would yield the result 0, and not -1, because boths1 and s2 are incremented by one in the while's expression, s1 and s2 will point to the
nul-terminators by the time the return statement is encountered, and thus
return *s1 - *s2; will result in returning 0.
tux4life
Nearly a Posting Maven
2,350 posts since Feb 2009
Reputation Points: 2,134
Solved Threads: 243
correction
int mstrcmp(const char *s1, const char *s2)
{
while((*s1 && *s2) && (*s1 == *s2))
s1++,s2++;
return *s1 - *s2;
}
Ancient Dragon
Retired & Loving It
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343
Here's a better idea for the return value: return an explicit value instead of allowing the possibility of signed integer overflow?
Dave Sinkula
long time no c
5,058 posts since Apr 2004
Reputation Points: 2,780
Solved Threads: 314
@Dave: how can *s1 - *s2 cause an integer overflow? The maximum values would be -255 (0 - 255). That's hardly even close to an integer overflow value.
Ancient Dragon
Retired & Loving It
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343
@AD: I'll leave that as an exercise for the programmer.
You don't really like portable programming or the design process involved, do you? If it happens to run on a particular compiler at a given moment in time, it appears "correct" to you?
Do you remember that qsort comparison function with the integer overflow issue?
No. I don't wantto continue. You are the lord of this roost. I am exhausted trying to get people to write portable code -- especially since you always come along and tell people to write implementation-specific stuff. Again, this is why I think of you as Daniweb's Herb Schildt. But he is a good author who has influenced many C and C++ programmers. It just sucks that it took him like 10 years to clean up his code. I think I need a break from all of this stupid bickering. Please take some time to wander into c.l.c and learn some new things.
Dave Sinkula
long time no c
5,058 posts since Apr 2004
Reputation Points: 2,780
Solved Threads: 314
@Dave: I didn't quite get you when you said:
Here's a better idea for the return value: return an explicit value instead of allowing the possibility of signed integer overflow? Also, you seem to do exactly the same as I and AD did in your code snippet: http://www.daniweb.com/code/snippet216567.html .
So, could you please clarify what you meant with returning an explicit value to avoid the possibility of a signed integer overflow ?
[EDIT]
@Dave:
Do you perhaps mean: return (int) *s1 - (int) *s2; ?
[/EDIT]
tux4life
Nearly a Posting Maven
2,350 posts since Feb 2009
Reputation Points: 2,134
Solved Threads: 243
Also, you seem to do exactly the same as I and AD did in your code snippet:
http://www.daniweb.com/code/snippet216567.html .
Ah. From back in the day when I could have possibly edited it. :( Dozens of times I've wished I could change that naive implementation; I've learned things in the past five years. But hey -- I no longer have any interest; you appear to. Enjoy solving the problem.
Your explicit casts do the usual arithmetic conversions? So that makes the implicit cast explicit. Do you see the problem then? What's (INT_MIN - 1) - 4, for example? I guess it's a nevermind; who cares; it works for me; code by happenstance(?).
[edit]Interesting:The sign of a nonzero value returned by the comparison functions memcmp, strcmp,
and strncmp is determined by the sign of the difference between the values of the first
pair of characters (both interpreted as unsigned char) that differ in the objects being
compared.
Dave Sinkula
long time no c
5,058 posts since Apr 2004
Reputation Points: 2,780
Solved Threads: 314
tux4life
Nearly a Posting Maven
2,350 posts since Feb 2009
Reputation Points: 2,134
Solved Threads: 243
@Dave: what are you rambling on about??? What does INT_MAX have to do with subtracting two character values?
>>You are the lord of this roost. I
Not because I am any smarter than anyone else -- I just liked to post and answer questions a lot. I never said I knew everything -- indeed I've screwed up lots of times.
>>especially since you always come along and tell people to write implementation-specific stuff
Not knowingly. If *s1 - *s2 is implementation specific then please tell us why instead of pussyfooting around it. If there is a case where that does not work, then please tell me because I'm all ears :)
Ancient Dragon
Retired & Loving It
30,049 posts since Aug 2005
Reputation Points: 5,662
Solved Threads: 2,343
Haven't I done this already?
Signed integer overflow is undefined behavior.
C'mon AD -- "it works ok for me?" :cheesy:Here's a better idea for the return value: return an explicit value instead of allowing the possibility of signed integer overflow?What does INT_MAX have to do with subtracting two character values? 3.3.6 Additive operators
Semantics
If both operands have arithmetic type, the usual arithmetic conversions are performed on them.3.2.1 Arithmetic operands
3.2.1.1 Characters and integers
A char, a short int, or an int bit-field, or their signed or unsigned varieties, or an object that has enumeration type, may be used in an expression wherever an int or unsigned int may be used. If an int can represent all values of the original type, the value is converted to an int; otherwise it is converted to an unsigned int. These are called the integral promotions.
The integral promotions preserve value including sign. As discussed earlier, whether a "plain" char is treated as signed is implementation-defined.
So let's see. We have a subtraction, which is done on two operands that are converted to int. The int may or may not be signed. If it is signed, then sign-extension could be performed. A byte is not necessarily 8 bits.
You know -- I have no idea why I am writing this. I've already mentioned the issue several times in previous posts. Why do I waste my time?
Dave Sinkula
long time no c
5,058 posts since Apr 2004
Reputation Points: 2,780
Solved Threads: 314