Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

strcmp() ? ;-)

39 views
Skip to first unread message

G G

unread,
Jun 18, 2019, 5:37:11 PM6/18/19
to
any hope of a change to mean

-------------

given strings : stringOne, stringTwo are equal

that strcmp( stringOne, stringTwo ) will return true with a value of 1 or
bool = true
--------------

given strings: stringOne, stringTwo are not equal

that strcmp( stringOne, stringTwo ) will return false with a value of 0 or
bool = false

and maybe a new function strcmpOrder( string string1, string string2 )
where if string1 comes before string2 returns a 1

if not return 0;


sorry, just as i'm reading chapter 4, and was into'ed to strcmp
i was just thinking...

lol

there is probably something better to come 14 more chapters to go.

:-)

Bart

unread,
Jun 18, 2019, 5:44:21 PM6/18/19
to
I doubt it. You might have to make your own functions, eg:


int streq(char* s, char* t) { return strcmp(s,t)==0;}
int strlt(char* s, char* t) { return strcmp(s,t)<0;}

james...@alumni.caltech.edu

unread,
Jun 18, 2019, 6:09:27 PM6/18/19
to
On Tuesday, June 18, 2019 at 5:37:11 PM UTC-4, G G wrote:
> any hope of a change to mean
>
> -------------
>
> given strings : stringOne, stringTwo are equal
>
> that strcmp( stringOne, stringTwo ) will return true with a value of 1 or
> bool = true

No, not a chance in the world. Even if enough people thought it would be
a good idea (and I can't imagine why they'd think that), there's too
much existing code that relies on the existing definition of strcmp() to
determine the relative order of stringOne and stringTwo, which would be
broken by such a change.

Why would you want such a change, anyway? if(strcmp(stringOne,
stringTwo)) will do the same thing with either the current definition or
your proposed change. The same is also true if strcmp(stringOne,
stringTwo) is used in a while(), do-while() or for() condition, or as
the first operand of ?:, or either operand of && or ||, or as the only
operand of !. Just about any reasonable use of strcmp() with your
proposed change would have the same behavior using strcmp() as
currently defined.

Ben Bacarisse

unread,
Jun 18, 2019, 6:24:55 PM6/18/19
to
james...@alumni.caltech.edu writes:

> On Tuesday, June 18, 2019 at 5:37:11 PM UTC-4, G G wrote:
>> any hope of a change to mean
>>
>> -------------
>>
>> given strings : stringOne, stringTwo are equal
>>
>> that strcmp( stringOne, stringTwo ) will return true with a value of 1 or
>> bool = true
<cut>
> Why would you want such a change, anyway? if(strcmp(stringOne,
> stringTwo)) will do the same thing with either the current definition or
> your proposed change.

Currently, strcmp(stringOne, stringTwo) returns 0 when the strings are
equal. The OP is proposing a change so that this would be 1.

<cut>
--
Ben.

James Kuyper

unread,
Jun 18, 2019, 8:01:46 PM6/18/19
to
I responded too quickly, without reading carefully enough. I assumed his
proposal was more sane than it actually was.
I should have said that "if(!strcmp(stringOne,stringTwo)) does the same
thing under the G G's proposal that if(strcmp(stringOne,stringTwo))",
with corresponding changes to the other comments I made.

Furthermore, I should have been more emphatic about the impossibility of
getting this changed - this will not merely break a lot of existing code
that uses strcmp() - it will break all existing code that uses it.

Keith Thompson

unread,
Jun 18, 2019, 9:03:57 PM6/18/19
to
G G <gdo...@gmail.com> writes:
> any hope of a change to mean
>
> -------------
>
> given strings : stringOne, stringTwo are equal
>
> that strcmp( stringOne, stringTwo ) will return true with a value of 1 or
> bool = true

No, because it would break existing code.

The result of strcmp() is not a boolean (yes/no, true/false) value.
It's a *number*, with different meanings for negative, zero, and
positive values.

I do see the advantages of having boolean string comparison functions
that work like the <, <=, ==, !=, >, and >= operators on scalars. And I
personally dislike code that treats strcmp()'s result as if it were
boolean, such as:
if (!strcmp(s1, s2) /* s1 and s2 equal */

If you really want boolean comparisons for strings you can roll your own:

#define STR_EQ(s1, s2) (strcmp((s1), (s2)) == 0)
#define STR_NE(s1, s2) (strcmp((s1), (s2)) != 0)
#define STR_LT(s1, s2) (strcmp((s1), (s2)) < 0)
#define STR_LE(s1, s2) (strcmp((s1), (s2)) <= 0)
#define STR_GT(s1, s2) (strcmp((s1), (s2)) > 0)
#define STR_GE(s1, s2) (strcmp((s1), (s2)) >= 0)

But with more experience working with C, I think you'll find that
these macros just aren't necessary. Any C programmer who has worked
with strings knows how strcmp() works, and can read `strcmp(s1, s2)
< 0` as easily as `STR_LT(s1, s2)`. In fact, the strcmp() version
is probably easier to read, because it doesn't require finding and
understanding the macro definition.

If a future version of the language added standard streq(), strne(),
et al as functions (possibly implemented as macros) to <string.h>,
I wouldn't object, but I doubt that's going to happen.

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Will write code for food.
void Void(void) { Void(); } /* The recursive call of the void */

Alf P. Steinbach

unread,
Jun 19, 2019, 12:02:47 AM6/19/19
to
On 18.06.2019 23:36, G G wrote:
> any hope of a change to mean
>
> -------------
>
> given strings : stringOne, stringTwo are equal
>
> that strcmp( stringOne, stringTwo ) will return true with a value of 1 or
> bool = true
> --------------
>
> given strings: stringOne, stringTwo are not equal
>
> that strcmp( stringOne, stringTwo ) will return false with a value of 0 or
> bool = false
>
> and maybe a new function strcmpOrder( string string1, string string2 )
> where if string1 comes before string2 returns a 1
>
> if not return 0;

The functions you mention are for comparing C strings, zero-terminated
strings represented by pointers.

Up at the C++ level `strcmp` corresponds to `std::string::compare`.

But `std::string` also offers the usual relational operators, like `==`,
`>` and so on, and the easiest way to get that notation for strings is
to just use `std::string`.


> sorry, just as i'm reading chapter 4, and was into'ed to strcmp
> i was just thinking...
>
> lol
>
> there is probably something better to come 14 more chapters to go.
>
> :-)

Hm, which book?

Anyway, the `strcmp`, `memcmp`, `std::string::compare` family of
functions, or at least the concept they embody, are about to have a
renaissance with the introduction of the spaceship operator in C++20.

The concept is roughly this: since the non-zero result values are not
specified one can use *any* values, and for example lexicographically
compare two struct instances this way:

struct S{ int x; int y; int z; };

auto compare( const S& a, const S& b )
-> int
{
if( const int r = a.x - b.x ) { return r; }
if( const int r = a.y - b.y ) { return r; }
if( const int r = a.z - b.z ) { return r; } // Redundant, but.
return 0;
}

Then the relational operators can easily and efficiently be expressed in
terms of, and automatically generated from, the single compare function.

A manual definition of one of them:

auto operator<( const S& a, const S& b )
-> bool
{ return compare( a, b ) < 0; }

If you try to express this function directly, without a function like
compare doing the brunt work, then you get into complexity where it's
very easy to step wrong, and then e.g. standard collections don't work.

That problem is reduced, though, when one learns about the `std::tuple`
based workaround,

auto operator<( const S&a, const S&b )
-> bool
{
using std::tie;
return tie( a.x, a.y, a.z ) < tie( b.x, b.y, b.z );
}

Here the `std::tuple::operator<` does the work, guaranteed correctly,
although possibly not as efficiently as compare. But on the third hand
with modern computers efficiency is no longer a matter of counting basic
operations. So it might be just as efficient, or even more.

It's just very much more work to do, with much redundancy, in general.


Cheers & hth.,

- Alf

Queequeg

unread,
Jun 19, 2019, 6:26:54 AM6/19/19
to
Bart <b...@freeuk.com> wrote:

> I doubt it. You might have to make your own functions, eg:

True.

> int streq(char* s, char* t) { return strcmp(s,t)==0;}
> int strlt(char* s, char* t) { return strcmp(s,t)<0;}

But please, please, please, use const in such situations. I've seen too
many functions that obviously don't modify the string, but don't care
about const, and it breaks the program logic.

Consider:

static void function(const char *argument)
{
static const char * const test = "test";
if (streq(argument, test))
{
// ...
}
}

--
https://www.youtube.com/watch?v=9lSzL1DqQn0

Juha Nieminen

unread,
Jun 19, 2019, 6:34:30 AM6/19/19
to
G G <gdo...@gmail.com> wrote:
> any hope of a change to mean
>
> -------------
>
> given strings : stringOne, stringTwo are equal
>
> that strcmp( stringOne, stringTwo ) will return true with a value of 1 or
> bool = true

No. On the contrary, the upcoming operator<=> will rely on the implementation
using exactly that kind of results for comparisons.

There's a reason for that.

Manfred

unread,
Jun 19, 2019, 8:01:36 AM6/19/19
to
As others have said, there's no chance for such a change.
In addition to being a breaking change for zillions of lines of existing
code, strcmp yields more than an equality test, it also delivers total
ordering on strings, which is a widely required feature.
And the implementation of strcmp yields ordering with zero extra cost
compared to a pure equality test.

Juha Nieminen

unread,
Jun 20, 2019, 5:41:42 AM6/20/19
to
Manfred <non...@add.invalid> wrote:
> In addition to being a breaking change for zillions of lines of existing
> code, strcmp yields more than an equality test, it also delivers total
> ordering on strings, which is a widely required feature.
> And the implementation of strcmp yields ordering with zero extra cost
> compared to a pure equality test.

For this reason even std::string offers a compare() function that has
a three-valued return value.

Suppose you are, for example, doing a binary search for a particular
string in an ordered array of strings. If you didn't have the
three-valued comparison, you would need to do the comparison
twice for the final position in order to determine if the string
is actually in the array or not. With the three-valued comparison
you don't need that extra comparison.
0 new messages