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

An interesting question

0 views
Skip to first unread message

Izzet

unread,
Dec 7, 2001, 3:49:57 PM12/7/01
to
yesterday a learner of C++ asked me a question which i still can't answer,
see if any of you can.
we all agree that ("0" < "1") evalutes to true,
but why does ("1" < "0") also evaluate to true?

all responses appreciated.

izzet.


Neil Butterworth

unread,
Dec 7, 2001, 3:55:56 PM12/7/01
to
"Izzet" <ma...@mrizzo.freeserve.co.uk> wrote in message
news:9ura0i$l1k$1...@newsg4.svr.pol.co.uk...

> yesterday a learner of C++ asked me a question which i still can't answer,

Why did they ask you?

> see if any of you can.
> we all agree that ("0" < "1") evalutes to true,

No we don't.

> but why does ("1" < "0") also evaluate to true?

It needn't.

When you compare two string literals using the '<' operator (or any other
comparison operator) you are comparing the addresses of the first character
in the literal. Exactly what those addresses are is implementation
dependant, and so is the result of the above comparisons.

NeilB


Ron Natalie

unread,
Dec 7, 2001, 3:58:52 PM12/7/01
to

Izzet wrote:
>
> yesterday a learner of C++ asked me a question which i still can't answer,
> see if any of you can.
> we all agree that ("0" < "1") evalutes to true,

I don't agree at all. What is being compared above is not the contents
of the strings, but the location of their allocation in memory. A string
literal (a set of characters in quotes like this) is allocated some place
statically in memory. You've got a couple of problems doing the comparison:

1. You aren't comparing the contents.
2. It's not valid to apply relational operations to pointers that aren't
part of the same object.

If you want to compare null terminated strings, you have to use something
like strcmp.

If you want a real string type, use the standard string type.

Kaz Kylheku

unread,
Dec 7, 2001, 4:06:19 PM12/7/01
to
In article <9ura0i$l1k$1...@newsg4.svr.pol.co.uk>, Izzet wrote:
>yesterday a learner of C++ asked me a question which i still can't answer,
>see if any of you can.
>we all agree that ("0" < "1") evalutes to true,
>but why does ("1" < "0") also evaluate to true?
>

You are comparing the addresses of distinct string literal objects.

Comparing pointers to distinct objects for other than exact equality
or inequality is undefined behavior.

Raf256

unread,
Dec 7, 2001, 4:16:56 PM12/7/01
to
"Izzet" <ma...@mrizzo.freeserve.co.uk> wrote in
news:9ura0i$l1k$1...@newsg4.svr.pol.co.uk:

> yesterday a learner of C++ asked me a question which i still can't
> answer, see if any of you can.

I think that You messed up a litle, You probably was thinking about :

> we all agree that ("0" < "1") evalutes to true,

('0' < '1') - is so because ASCII code of '0' is 48, and '1'=49,
so it's same as :
( 48 < 49 )

> but why does ("1" < "0") also evaluate to true?

(1 < '0') this is so because '0' = 48, so it's same as :
(1 < 48 )

--
Raf256 ##############################################################
,--, _ ,- _ _ _ ###############################################
|,-'`_|_|_ `_||_'|_' # raf...@go2.pl ## :( #########################
| `\|_| | |_,,_||_| ###############################################

Homer Meyer

unread,
Dec 7, 2001, 4:42:42 PM12/7/01
to

"Raf256" <raf...@go2.pl> wrote in message
news:Xns9170E33E7F817...@213.180.128.20...

> "Izzet" <ma...@mrizzo.freeserve.co.uk> wrote in
> news:9ura0i$l1k$1...@newsg4.svr.pol.co.uk:
>
> > yesterday a learner of C++ asked me a question which i still can't
> > answer, see if any of you can.
>
> I think that You messed up a litle, You probably was thinking about :
>
> > we all agree that ("0" < "1") evalutes to true,
> ('0' < '1') - is so because ASCII code of '0' is 48, and '1'=49,
> so it's same as :
> ( 48 < 49 )

And you shouldn't assume that every system uses ASCII. In this case however
'0' < '1' is always true, because the standard guarantees that '0' - '9' are
contiguous and in order in the character set. However, they may not have
the values 48 and 49. It could be 30 and 31 instead (or any other two
consecutive positive integers).


Default User

unread,
Dec 7, 2001, 5:29:06 PM12/7/01
to
Raf256 wrote:
>
> "Izzet" <ma...@mrizzo.freeserve.co.uk> wrote in
> news:9ura0i$l1k$1...@newsg4.svr.pol.co.uk:
>
> > yesterday a learner of C++ asked me a question which i still can't
> > answer, see if any of you can.
>
> I think that You messed up a litle, You probably was thinking about :
>
> > we all agree that ("0" < "1") evalutes to true,
> ('0' < '1') - is so because ASCII code of '0' is 48, and '1'=49,
> so it's same as :
> ( 48 < 49 )

No, it's not. The ASCII code set is one of the possible ones that can be
used by implementations. Some most assuredly do not us it.

However, the Standard does guarantee a few things about the digit
characters, that they are consectutive and increasing from '0' to '9'.

This is convenient, since then any digit - '0' will render the numeric
value.

It the example you have (and we don't know if it is what the OP is
talking about) the reason '0' < '1' is that the Standard guarantees it,
not because it is that way in ASCII.

> > but why does ("1" < "0") also evaluate to true?
> (1 < '0') this is so because '0' = 48, so it's same as :
> (1 < 48 )

Now you are completely out in left field. An implementation could decide
that '0' == 1 which would mean that 1 < '0' would not be true at all.

Brian Rodenborn

Mike Wahler

unread,
Dec 7, 2001, 6:40:49 PM12/7/01
to

Izzet wrote in message <9ura0i$l1k$1...@newsg4.svr.pol.co.uk>...

>yesterday a learner of C++ asked me a question which i still can't answer,
>see if any of you can.
>we all agree that ("0" < "1") evalutes to true,

Perhaps, but not necessarily. This relationship
depends upon those strings' locations in memory.

We can say however, that

("0" != "1")

>but why does ("1" < "0") also evaluate to true?

It might, it might not, for the same reasons given above.

-Mike

Micah Cowan

unread,
Dec 7, 2001, 6:47:38 PM12/7/01
to
"Izzet" <ma...@mrizzo.freeserve.co.uk> writes:

> yesterday a learner of C++ asked me a question which i still can't answer,
> see if any of you can.
> we all agree that ("0" < "1") evalutes to true,

No, we don't. The above expression is unspecified. In C, it would be
undefined. It could just as easily be false as true - there are no
guarantees as to which NTBS (C-string) pointer comes before which.

> but why does ("1" < "0") also evaluate to true?

Ditto.

Micah

Micah Cowan

unread,
Dec 7, 2001, 6:48:03 PM12/7/01
to
k...@ashi.footprints.net (Kaz Kylheku) writes:

(Not in C++ - just C).

Micah

Victor Bazarov

unread,
Dec 7, 2001, 7:09:37 PM12/7/01
to
"Micah Cowan" <mi...@cowanbox.com> wrote...


It is OK to compare pointers to _distinct_ objects if both objects
are members of the same object or elements of the same array (or
both point "one past the end of the same array". Pointers to any
other _distinct_ objects cannot be compared using <,>,<=, or >=.
See Standard, clause 5, subclause "Relational operators".

Victor
--
Please remove capital A's from my address when replying by mail


David Hilsee

unread,
Dec 7, 2001, 9:27:40 PM12/7/01
to

"Victor Bazarov" <vAba...@dAnai.com> wrote in message
news:5TcQ7.1265$He.2...@sea-read.news.verio.net...

I feel like I need some clarification here. The word that the standard uses
to describe the result of using those comparison operators is "unspecified".
The definition of "unspecified" is as follows:

behavior, for a well-formed program construct and correct data, that depends
on the implementation. The implementation is not required to document which
behavior occurs. [Note: usually, the range of possible behaviors is
delineated by this International Standard. ]

The difference between "unspecified" and "undefined" seems to be the range
of behaviors that are allowed. Undefined behavior generally means
unrestricted, in the sense that anything could happen.

Normally, I try to avoid worrying about such technicalities, but I could see
a programmer writing code similar to the following:

class Table
{
std::vector<Element*> internal_table;
public:
bool IsPresent ( Element* to_find )
{
// keep internal_table sorted and...
return
std::binary_search
(
internal_table.begin(),
internal_table.end(),
to_find
);
}
};


This doesn't seem like a contrived situation to me, so I have to ask: is
this ok? If I were to say what the "range" of the behavior of comparing
pointers with < is, I would say that it would be "evaluate to true or
false". I'm not sure if the range also includes always evaluating to the
same value when comparing the same pointers, or possibly other behaviors
that I might normally expect.

--
David Hilsee


Victor Bazarov

unread,
Dec 8, 2001, 1:37:30 AM12/8/01
to
"David Hilsee" <davidhi...@yahoo.com> wrote...

Right. Unspecified, of course. Pointers _may_ be compared,
the result is not required to be one way or the other.

> [...]


> Normally, I try to avoid worrying about such technicalities, but I could
see
> a programmer writing code similar to the following:
>
> class Table
> {
> std::vector<Element*> internal_table;
> public:
> bool IsPresent ( Element* to_find )
> {
> // keep internal_table sorted and...
> return
> std::binary_search
> (
> internal_table.begin(),
> internal_table.end(),
> to_find
> );
> }
> };
>
>
> This doesn't seem like a contrived situation to me, so I have to ask: is
> this ok? If I were to say what the "range" of the behavior of comparing
> pointers with < is, I would say that it would be "evaluate to true or
> false". I'm not sure if the range also includes always evaluating to the
> same value when comparing the same pointers, or possibly other behaviors
> that I might normally expect.

Since you are not expecting the result to be a particular 'true'
or 'false', it's probably OK. However, I don't remember that
in the Standard it says that for pointers the relational operators
are transitive (if a < b and b < c then a < c) (is 'transitive'
the right term? It is too late at night for me to be sure...)

Catch my drift?

Izzet

unread,
Dec 8, 2001, 8:26:46 AM12/8/01
to
thanks for the responses. firstly, for anyone still trying to understand.
the expression always evalutes to true. ("ab" < "cd"), "ab" is first given a
place in memory (stack), then "cd" is given one, and since the pionter to
"ab" always points to an address less than that of the address of "cd" the
expression is always true. likewise ("ab" > "cd") always evaluates to false.
to get the desired effect you need to compare, not the pointer addresses,
but the values which the pointers hold, which is done by writing (*"ab" <
*"cd").
like me, you might be asking why char, int, double, etc are not implemented
this way, since you can certainly do (1 < 2) or ('a' <= 'b'). any answers?

izzet.


"Izzet" <ma...@mrizzo.freeserve.co.uk> wrote in message
news:9ura0i$l1k$1...@newsg4.svr.pol.co.uk...

Umesh P Nair

unread,
Dec 8, 2001, 11:52:30 AM12/8/01
to
On Sat, 8 Dec 2001 13:26:46 -0000, "Izzet"
<ma...@mrizzo.freeserve.co.uk> wrote:

>thanks for the responses. firstly, for anyone still trying to understand.
>the expression always evalutes to true. ("ab" < "cd"), "ab" is first given a
>place in memory (stack), then "cd" is given one, and since the pionter to
>"ab" always points to an address less than that of the address of "cd" the
>expression is always true. likewise ("ab" > "cd") always evaluates to false.

May be true on your compiler, but this is not guaranteed. It may
evaluate to true or false. It is completely unspecified.

>to get the desired effect you need to compare, not the pointer addresses,
>but the values which the pointers hold, which is done by writing (*"ab" <
>*"cd").

What is the language you are referring to? C++ ? I reaaly sympathise
to the folks who asked you C++ doubts.

>like me, you might be asking why char, int, double, etc are not implemented
>this way, since you can certainly do (1 < 2) or ('a' <= 'b'). any answers?
>

Because "abc" resolves to a character pointer. The comparison works on
the pointer value. To compare the value pointed by that, you need to
use a function - strcmp() or strncmp() - and not the relational
operators.

- Umesh

--
Umesh P Nair
Remove all 'z's in my e-mail ID if you
want to reply only to me

Richard Norman

unread,
Dec 8, 2001, 12:31:52 PM12/8/01
to
On Sat, 08 Dec 2001 16:52:30 GMT, umesh...@mentzor.com (Umesh P
Nair) wrote:

>On Sat, 8 Dec 2001 13:26:46 -0000, "Izzet"
><ma...@mrizzo.freeserve.co.uk> wrote:
>
>>thanks for the responses. firstly, for anyone still trying to understand.
>>the expression always evalutes to true. ("ab" < "cd"), "ab" is first given a
>>place in memory (stack), then "cd" is given one, and since the pionter to
>>"ab" always points to an address less than that of the address of "cd" the
>>expression is always true. likewise ("ab" > "cd") always evaluates to false.
>
>May be true on your compiler, but this is not guaranteed. It may
>evaluate to true or false. It is completely unspecified.
>

On my compiler (Microsoft VC+6 debug mode) I get "ab" > "cd", it
evaluates to true. You are comparing addresses where the strings are
stored, not the string values. But they are not necessarily on the
stack, "ab" is not necessarily allocated first, and "ab" is not
necessarily allocated at a lower memory address than "cd".


Mike Wahler

unread,
Dec 8, 2001, 4:15:30 PM12/8/01
to

Izzet wrote in message <9ut4di$nmi$1...@newsg1.svr.pol.co.uk>...

>thanks for the responses. firstly, for anyone still trying to understand.
>the expression always evalutes to true. ("ab" < "cd"), "ab" is first

Perhaps first, perhaps not.

>given a
>place in memory (stack),

Perhaps on a 'stack', perhaps not.

> then "cd" is given one,

Perhaps first, perhaps not.

> and since the pionter to
>"ab" always points to an address less than that of the address of "cd"

This is an invalid assumption. Also note that a 'stack'
could be stored 'upside down' in memory.

>the
>expression is always true.
> likewise ("ab" > "cd") always evaluates to false.

Your reasoning is faulty. Also note that others
have pointed out that comparing addresses of objects
that are not part of the same aggregrate (e.g. 'struct'
or array) with comparison operator othere than '=='
is undefined.

>to get the desired effect

I'm not sure what the 'desired efffect' is. :-)

>you need to compare, not the pointer addresses,
>but the values which the pointers hold, which is done by writing (*"ab" <
>*"cd").

That expression compares the first character of one
string with the first character of the other.

>like me, you might be asking why char, int, double, etc are not implemented
>this way,

Implemented what way? Numeric type objects are for
storing and calculating numeric results. Pointers
are for storing addresses.

> since you can certainly do (1 < 2) or ('a' <= 'b'). any answers?

The numerical types, e.g. 'int' and 'char' in the above
line, are integral types, for which numerical and relational
operations are well-defined. Pointers are not numerical
types, in the arithmetic sense of the term. They're an
*access mechanism*. Certain 'numerical' operators are
allowed to be used with pointers in certain contexts,
but with specialized meanings. E.g.:

int array[100];
int *p = &array[0];
++p; // this does not mean 'add integral value 1 to p'
// it means 'change the contained address to point
// sizeof(int) bytes past &array[0]'

The mechanism I describe here is known officially as
'pointer arithmetic', but which is distinct from 'conventional'
arithmetic as when computing with numerical types.

HTH,
-Mike

Izzet

unread,
Dec 9, 2001, 7:31:47 AM12/9/01
to
okay, thanks everyone, tommorow im going to confuse the hell out of someone.
so i got ("a" < "b") compares pointer values, which can be anything
depending on the compiler, and (1<2) works because it is comparing integral
types, which are all well defined.

izzet.


"Izzet" <ma...@mrizzo.freeserve.co.uk> wrote in message
news:9ura0i$l1k$1...@newsg4.svr.pol.co.uk...

Micah Cowan

unread,
Dec 10, 2001, 10:45:29 PM12/10/01
to
"Victor Bazarov" <vAba...@dAnai.com> writes:

By "distinct" I meant not part of the same object. Thanks for the
clarification, though.

Micah

Micah Cowan

unread,
Dec 10, 2001, 10:48:11 PM12/10/01
to
"David Hilsee" <davidhi...@yahoo.com> writes:

In the C++ standard, yes. That's why I said, "Not in C++ - just C".
The C standard currently says the results are "undefined". C++
decided to be a little kinder, perhaps.

Micah

Magmai Kai Holmlor

unread,
Dec 13, 2001, 11:19:03 PM12/13/01
to
In this case it's obvious that we comparing char*'s, and consequentially
which ever one is defined first is going to be loaded lower in the memory
space, and thus whichever string constant is defined on the left will
(usually) be less. The results are spurious though, because there's a large
number of things can affect where those string are loaded. If "0" or "1"
was used elsewhere in the program would affect it becase C and C++ compilers
are allow to reuse string literals. You could very well get different
results in a debug vs a release build, too.

If it's surprising that ("1" < "0") is true, you have yet to make the mental
leep of understanding the abstraction pointers provide. Or perhaps you're
accustom to other languages that don't allow pointers, and only provide
classes to manipulate strings, not raw pointers.

"Micah Cowan" <mi...@cowanbox.com> wrote in message
news:yu8vgfe...@mcowan-linux.transmeta.com...

Micah Cowan

unread,
Dec 14, 2001, 3:55:26 PM12/14/01
to
"Magmai Kai Holmlor" <magm...@mediaone.net> writes:

> In this case it's obvious that we comparing char*'s, and consequentially
> which ever one is defined first is going to be loaded lower in the memory

> space.

This has nothing whatsoever to do with anything. The results are not
specified *means* the results are not specified. There are no
guarantees that a variable declared earlier actually gets loaded
earlier (same doesn't apply for class members, however).

> and thus whichever string constant is defined on the left will
> (usually) be less.

Not always - and no portable assumption may be made.

> The results are spurious though, because there's a large
> number of things can affect where those string are loaded. If "0" or "1"
> was used elsewhere in the program would affect it becase C and C++ compilers
> are allow to reuse string literals. You could very well get different
> results in a debug vs a release build, too.
>
> If it's surprising that ("1" < "0") is true,

It is *not* (necessarily) true - that's what we've been telling you.

> you have yet to make the mental
> leep of understanding the abstraction pointers provide.

Huh! Do I, now? :)

> Or perhaps you're
> accustom to other languages that don't allow pointers, and only provide
> classes to manipulate strings, not raw pointers.

Nonsense. I grew up on C. In C, it's not only unspecified, it's
*undefined*. That is, as far as the standard is concerned, your
computer can blow up in your face when you compare ("0" < "1").

Also, in the even that you're perhaps used to newsgroups that allow
sloppy top-posting, please learn to bottom-post - people now have to
jump around in this post to find the context, which I'm too lazy to
fix.

David Hilsee

unread,
Dec 16, 2001, 12:44:34 AM12/16/01
to
<snip>

For those interested, I did find a reference to the standard that clarifies
the matter (20.3.3.8). Thanks be to groups.google.com. This question was
asked last year in February. Apparently <, <=, >, >= are not required to
define an order, but std::less, std::greater, std::greater_equal, and
std::less_equal are.

Correct me if I'm wrong, but I believe that implies that the call to
binary_search in the above example should be changed to:

std::binary_search
(
internal_table.begin(),
internal_table.end(),

to_find,
std::less<Element*>()
);

Also, any usage of sorting or other comparisons should probably do the same
if the library does not use the std::less comparison by default.

--
David Hilsee


Magmai Kai Holmlor

unread,
Dec 17, 2001, 9:26:38 PM12/17/01
to

"Micah Cowan" <mi...@cowanbox.com> wrote in message
news:yu8pu5h...@mcowan-linux.transmeta.com...

> "Magmai Kai Holmlor" <magm...@mediaone.net> writes:
>
> > In this case it's obvious that we comparing char*'s, and consequentially
> > which ever one is defined first is going to be loaded lower in the
memory
> > space.
>
> This has nothing whatsoever to do with anything. The results are not
> specified *means* the results are not specified. There are no
> guarantees that a variable declared earlier actually gets loaded
> earlier (same doesn't apply for class members, however).
My wording was too convoluted: I was asserting that: /The/ order may not be
garuanteed but /an/ order is.
Further, it is possible to determine that order for a particular compiler.
I as trying to say that it can be described as 'spurious', instead of the
more general 'undefied'.

>
> > and thus whichever string constant is defined on the left will
> > (usually) be less.
>
> Not always - and no portable assumption may be made.

Portable? It's not applicable code, and now we're trying to port it! :)

>
> > The results are spurious though, because there's a large
> > number of things can affect where those string are loaded. If "0" or
"1"
> > was used elsewhere in the program would affect it becase C and C++
compilers
> > are allow to reuse string literals. You could very well get different
> > results in a debug vs a release build, too.
> >
> > If it's surprising that ("1" < "0") is true,
>
> It is *not* (necessarily) true - that's what we've been telling you.

"If it's surprising that ("1" < "0") could be true"


>
> > you have yet to make the mental
> > leep of understanding the abstraction pointers provide.
>
> Huh! Do I, now? :)

Not you :p, I meant someone who doesn't understand how "1" < "0" could
possibly be false.

>
> > Or perhaps you're
> > accustom to other languages that don't allow pointers, and only provide
> > classes to manipulate strings, not raw pointers.
>
> Nonsense. I grew up on C. In C, it's not only unspecified, it's

I should have said they, sorry. If a student doesn't understand that, they
likely need more help with pointers.

> *undefined*. That is, as far as the standard is concerned, your
> computer can blow up in your face when you compare ("0" < "1").

But what compiler would? You can give this situation a more accurate
specification than undefined.

>
> Also, in the even that you're perhaps used to newsgroups that allow
> sloppy top-posting, please learn to bottom-post - people now have to
> jump around in this post to find the context, which I'm too lazy to
> fix.

Sorry, I will do so in the future.

[snip]


0 new messages