all responses appreciated.
izzet.
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
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.
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.
> 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 ## :( #########################
| `\|_| | |_,,_||_| ###############################################
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).
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
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
> 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
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
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
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.
"Izzet" <ma...@mrizzo.freeserve.co.uk> wrote in message
news:9ura0i$l1k$1...@newsg4.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 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
>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".
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.
"Izzet" <ma...@mrizzo.freeserve.co.uk> wrote in message
news:9ura0i$l1k$1...@newsg4.svr.pol.co.uk...
By "distinct" I meant not part of the same object. Thanks for the
clarification, though.
Micah
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
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...
> 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.
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
>
> > 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]