Why can't we do three-way comparison in C++? [duplicate]Comparing a variable to a range of valuesWhat is the <=> operator in C++?I am having a problem with the logic of range checking in C++What are the differences between a pointer variable and a reference variable in C++?The Definitive C++ Book Guide and ListWhy is “using namespace std;” considered bad practice?What is the “-->” operator in C++?Why do we need virtual functions in C++?What is The Rule of Three?Easiest way to convert int to string in C++Why are elementwise additions much faster in separate loops than in a combined loop?Why is reading lines from stdin much slower in C++ than Python?Why is processing a sorted array faster than processing an unsorted array?
What kind of chart is this?
What is this plant I saw for sale at a Romanian farmer's market?
What mathematical theory is required for high frequency trading?
How is the idea of "girlfriend material" naturally expressed in Russian?
How can I take pictures like these examples with a yellowish tone and point & shoot film camera look?
Why is it 出差去 and not 去出差?
Why do you need to heat the pan before heating the olive oil?
Why are there no file insertion syscalls
Setting up the trap
Is there any way to revive my Sim?
reverse a call to mmap()
How to ask if I can mow my neighbor's lawn
Why does a Force divides equally on a Multiple Support/Legs?
What is the name of the person who reconciled a line from Rudram to dakshinamurthy and Adi Shankaracharya?
What could be the physiological mechanism for a biological Geiger counter?
My student in one course asks for paid tutoring in another course. Appropriate?
sudo passwd username keeps asking for the current password
Predict the product from the reaction
Basic power tool set for Home repair and simple projects
"Correct me if I'm wrong"
Is there any possible way to get these hearts as Adult Link?
Can a character learn spells from someone else's spellbook and then sell it?
I just entered the USA without passport control at Atlanta airport
How to modify a string without altering its text properties
Why can't we do three-way comparison in C++? [duplicate]
Comparing a variable to a range of valuesWhat is the <=> operator in C++?I am having a problem with the logic of range checking in C++What are the differences between a pointer variable and a reference variable in C++?The Definitive C++ Book Guide and ListWhy is “using namespace std;” considered bad practice?What is the “-->” operator in C++?Why do we need virtual functions in C++?What is The Rule of Three?Easiest way to convert int to string in C++Why are elementwise additions much faster in separate loops than in a combined loop?Why is reading lines from stdin much slower in C++ than Python?Why is processing a sorted array faster than processing an unsorted array?
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
This question already has an answer here:
Comparing a variable to a range of values
7 answers
To summarize it quickly, why isn't 2 < x < 9 equal to 2 < x && x < 9?
This is the test code I've written:
#include <iostream>
int main()
int nums[] = 5 , 1, 10;
// We are gonna check if the number is in the range 2 - 9
for (auto e : nums)
if (2 < e < 9)
std::cout << "2 < " << e << " < 9" << std::endl;
if(2 < e && e < 9)
std::cout << "2 < " << e << " and " << e << " < 9" << std::endl;
std::cin.get();
Here is the output I'm getting:
2 < 5 < 9
2 < 5 and 5 < 9
2 < 1 < 9
2 < 10 < 9
It looks like only 2 < e && e < 9 works correctly.
c++
marked as duplicate by jww, Mahmoud Fayez, Cody Gray♦
StackExchange.ready(function()
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();
);
);
);
Jun 11 at 1:03
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
|
show 6 more comments
This question already has an answer here:
Comparing a variable to a range of values
7 answers
To summarize it quickly, why isn't 2 < x < 9 equal to 2 < x && x < 9?
This is the test code I've written:
#include <iostream>
int main()
int nums[] = 5 , 1, 10;
// We are gonna check if the number is in the range 2 - 9
for (auto e : nums)
if (2 < e < 9)
std::cout << "2 < " << e << " < 9" << std::endl;
if(2 < e && e < 9)
std::cout << "2 < " << e << " and " << e << " < 9" << std::endl;
std::cin.get();
Here is the output I'm getting:
2 < 5 < 9
2 < 5 and 5 < 9
2 < 1 < 9
2 < 10 < 9
It looks like only 2 < e && e < 9 works correctly.
c++
marked as duplicate by jww, Mahmoud Fayez, Cody Gray♦
StackExchange.ready(function()
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();
);
);
);
Jun 11 at 1:03
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
9
Because e.g.2 < 10 < 9will be interpreted as(2 < 10) < 9, that is1 < 9which is true
– Federico klez Culloca
Jun 10 at 12:20
3
Because the compiler is processing the operators from left to right and with precedence in mind.2 < 10 < 9is therefore processed as(2 < 10) < 9, from which we get1 < 9as 2 is less then 10 results intotruewhich is interpreted as 1.
– Anže
Jun 10 at 12:21
5
This notation makes a lot of sense in mathematical text but is hard to consistently capture with a parser, without confusing parsing rules. In particular, '>' would no longer be a binary operator that applies directly to its left hand and right hand neighbors, and parsers would have to look in a larger context window for meaning.
– jwimberley
Jun 10 at 12:21
10
Nitpicking about terminology, in the upcoming C++20 standard there will come a three-way comparison operator. But it doesn't do what you want either, so please be careful when using that term.
– Some programmer dude
Jun 10 at 12:24
6
The only language I'm aware that has such a comparison is Python, wherea op1 b op2 cis just syntactic sugar fora op1 b and b op2 c. (So Python also allows weird things like2 < 3 != 1(which is true) and1 < 2 in [3,4,5](which is false).)
– molbdnilo
Jun 10 at 12:32
|
show 6 more comments
This question already has an answer here:
Comparing a variable to a range of values
7 answers
To summarize it quickly, why isn't 2 < x < 9 equal to 2 < x && x < 9?
This is the test code I've written:
#include <iostream>
int main()
int nums[] = 5 , 1, 10;
// We are gonna check if the number is in the range 2 - 9
for (auto e : nums)
if (2 < e < 9)
std::cout << "2 < " << e << " < 9" << std::endl;
if(2 < e && e < 9)
std::cout << "2 < " << e << " and " << e << " < 9" << std::endl;
std::cin.get();
Here is the output I'm getting:
2 < 5 < 9
2 < 5 and 5 < 9
2 < 1 < 9
2 < 10 < 9
It looks like only 2 < e && e < 9 works correctly.
c++
This question already has an answer here:
Comparing a variable to a range of values
7 answers
To summarize it quickly, why isn't 2 < x < 9 equal to 2 < x && x < 9?
This is the test code I've written:
#include <iostream>
int main()
int nums[] = 5 , 1, 10;
// We are gonna check if the number is in the range 2 - 9
for (auto e : nums)
if (2 < e < 9)
std::cout << "2 < " << e << " < 9" << std::endl;
if(2 < e && e < 9)
std::cout << "2 < " << e << " and " << e << " < 9" << std::endl;
std::cin.get();
Here is the output I'm getting:
2 < 5 < 9
2 < 5 and 5 < 9
2 < 1 < 9
2 < 10 < 9
It looks like only 2 < e && e < 9 works correctly.
This question already has an answer here:
Comparing a variable to a range of values
7 answers
c++
c++
edited Jun 10 at 13:33
Boann
38.1k1291123
38.1k1291123
asked Jun 10 at 12:17
Marcin PoloczekMarcin Poloczek
1146
1146
marked as duplicate by jww, Mahmoud Fayez, Cody Gray♦
StackExchange.ready(function()
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();
);
);
);
Jun 11 at 1:03
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
marked as duplicate by jww, Mahmoud Fayez, Cody Gray♦
StackExchange.ready(function()
if (StackExchange.options.isMobile) return;
$('.dupe-hammer-message-hover:not(.hover-bound)').each(function()
var $hover = $(this).addClass('hover-bound'),
$msg = $hover.siblings('.dupe-hammer-message');
$hover.hover(
function()
$hover.showInfoMessage('',
messageElement: $msg.clone().show(),
transient: false,
position: my: 'bottom left', at: 'top center', offsetTop: -7 ,
dismissable: false,
relativeToBody: true
);
,
function()
StackExchange.helpers.removeMessages();
);
);
);
Jun 11 at 1:03
This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.
9
Because e.g.2 < 10 < 9will be interpreted as(2 < 10) < 9, that is1 < 9which is true
– Federico klez Culloca
Jun 10 at 12:20
3
Because the compiler is processing the operators from left to right and with precedence in mind.2 < 10 < 9is therefore processed as(2 < 10) < 9, from which we get1 < 9as 2 is less then 10 results intotruewhich is interpreted as 1.
– Anže
Jun 10 at 12:21
5
This notation makes a lot of sense in mathematical text but is hard to consistently capture with a parser, without confusing parsing rules. In particular, '>' would no longer be a binary operator that applies directly to its left hand and right hand neighbors, and parsers would have to look in a larger context window for meaning.
– jwimberley
Jun 10 at 12:21
10
Nitpicking about terminology, in the upcoming C++20 standard there will come a three-way comparison operator. But it doesn't do what you want either, so please be careful when using that term.
– Some programmer dude
Jun 10 at 12:24
6
The only language I'm aware that has such a comparison is Python, wherea op1 b op2 cis just syntactic sugar fora op1 b and b op2 c. (So Python also allows weird things like2 < 3 != 1(which is true) and1 < 2 in [3,4,5](which is false).)
– molbdnilo
Jun 10 at 12:32
|
show 6 more comments
9
Because e.g.2 < 10 < 9will be interpreted as(2 < 10) < 9, that is1 < 9which is true
– Federico klez Culloca
Jun 10 at 12:20
3
Because the compiler is processing the operators from left to right and with precedence in mind.2 < 10 < 9is therefore processed as(2 < 10) < 9, from which we get1 < 9as 2 is less then 10 results intotruewhich is interpreted as 1.
– Anže
Jun 10 at 12:21
5
This notation makes a lot of sense in mathematical text but is hard to consistently capture with a parser, without confusing parsing rules. In particular, '>' would no longer be a binary operator that applies directly to its left hand and right hand neighbors, and parsers would have to look in a larger context window for meaning.
– jwimberley
Jun 10 at 12:21
10
Nitpicking about terminology, in the upcoming C++20 standard there will come a three-way comparison operator. But it doesn't do what you want either, so please be careful when using that term.
– Some programmer dude
Jun 10 at 12:24
6
The only language I'm aware that has such a comparison is Python, wherea op1 b op2 cis just syntactic sugar fora op1 b and b op2 c. (So Python also allows weird things like2 < 3 != 1(which is true) and1 < 2 in [3,4,5](which is false).)
– molbdnilo
Jun 10 at 12:32
9
9
Because e.g.
2 < 10 < 9 will be interpreted as (2 < 10) < 9, that is 1 < 9 which is true– Federico klez Culloca
Jun 10 at 12:20
Because e.g.
2 < 10 < 9 will be interpreted as (2 < 10) < 9, that is 1 < 9 which is true– Federico klez Culloca
Jun 10 at 12:20
3
3
Because the compiler is processing the operators from left to right and with precedence in mind.
2 < 10 < 9 is therefore processed as (2 < 10) < 9, from which we get 1 < 9 as 2 is less then 10 results into true which is interpreted as 1.– Anže
Jun 10 at 12:21
Because the compiler is processing the operators from left to right and with precedence in mind.
2 < 10 < 9 is therefore processed as (2 < 10) < 9, from which we get 1 < 9 as 2 is less then 10 results into true which is interpreted as 1.– Anže
Jun 10 at 12:21
5
5
This notation makes a lot of sense in mathematical text but is hard to consistently capture with a parser, without confusing parsing rules. In particular, '>' would no longer be a binary operator that applies directly to its left hand and right hand neighbors, and parsers would have to look in a larger context window for meaning.
– jwimberley
Jun 10 at 12:21
This notation makes a lot of sense in mathematical text but is hard to consistently capture with a parser, without confusing parsing rules. In particular, '>' would no longer be a binary operator that applies directly to its left hand and right hand neighbors, and parsers would have to look in a larger context window for meaning.
– jwimberley
Jun 10 at 12:21
10
10
Nitpicking about terminology, in the upcoming C++20 standard there will come a three-way comparison operator. But it doesn't do what you want either, so please be careful when using that term.
– Some programmer dude
Jun 10 at 12:24
Nitpicking about terminology, in the upcoming C++20 standard there will come a three-way comparison operator. But it doesn't do what you want either, so please be careful when using that term.
– Some programmer dude
Jun 10 at 12:24
6
6
The only language I'm aware that has such a comparison is Python, where
a op1 b op2 c is just syntactic sugar for a op1 b and b op2 c. (So Python also allows weird things like 2 < 3 != 1 (which is true) and 1 < 2 in [3,4,5] (which is false).)– molbdnilo
Jun 10 at 12:32
The only language I'm aware that has such a comparison is Python, where
a op1 b op2 c is just syntactic sugar for a op1 b and b op2 c. (So Python also allows weird things like 2 < 3 != 1 (which is true) and 1 < 2 in [3,4,5] (which is false).)– molbdnilo
Jun 10 at 12:32
|
show 6 more comments
6 Answers
6
active
oldest
votes
The expression
2 < x < 9
is grouped as
(2 < x) < 9
And since 2 < x is either false (0) or true (1), and both are less than 9, it's always true.
So unless you use overloaded operators for a non-built-in type x (then a 3-way comparison would be possible if 2 < x were to return an instance of a proxy object on which < is defined), if you want to test if x is in the interval (2, 9) you need to write it the way you have.
5
So, that's not a three-way comparison.
– Lightness Races in Orbit
Jun 10 at 12:21
add a comment |
Just because this language doesn't have that feature.
It could have been made to, but this would contrast with C in a non-compatible way.
C could have been made to, but the designers simply didn't do that.
You already have the correct way to do it.
Some different (and newer!) languages do support this.
1
If contrasting with C was an issue, all C code would be compilable with a C++ compiler, which is not the case.
– Federico klez Culloca
Jun 10 at 12:24
16
@FedericoklezCulloca That's a bit of a fallacy. It is quite clear that the language designers have gone to great lengths to ensure a high level of compatibility with C. No, it's not a strict superset, but it's really, really close. Fundamentally changing the way operators work would be a big no-no.
– Lightness Races in Orbit
Jun 10 at 12:25
2
@FedericoklezCulloca C++ was explcitly designed to be mostly backwards compatibile with C. Of course there are places it couldn't be, but for basic syntax rules like this, the C way was maintained.
– NathanOliver
Jun 10 at 12:27
1
I doubt that any C programmer writes such code, because the result is nonsense. There was a proposal for this but it was rejected due to parsing issues in some compilers.
– Rakete1111
Jun 10 at 12:39
My favourite example:&and&&. Actually, it would have been much more comfortable in pure C++ if they opted for breaking the compatibility with C and had given the bitwise operator higher precedence than the comparison operators. This precedence as is dates back to the times the&&operator had not yet been invented in C. But if we drop this isolated view on C++, hell breaks loose faster than we even could ever measure...
– Aconcagua
Jun 10 at 12:47
|
show 2 more comments
the comparison operators in c++ takes as an argument two values.
when you are writing a<b it is the same as operator<(a,b).
and the return value of operator< is bool.
when you are calling a function in c++, it is computing the expression of its arguments and then passing it to that function, so calling a<b<c is same asoperator<(operator<(a,b),c)
basically, the answer to your question is that in c++ there is no comparison operator (less than, greater than...) that takes three arguments
add a comment |
If C++ chose to redefine a < b < c to better align with the mathematical notation, it would be ambiguous with the current meaning. The current meaning is a bit silly and is comparing bools with numbers, but there may be tricky code relying on this detail in production use.
And as C++ allows you to define your own types with operators, it would have to expose the new ternary < to you as well, so you could make one for your type. Which would open new cans of worms if you only define a binary < but no ternary < for your type - should the compiler start shouting at you?
1
"your own types with operators, it would have to expose the new ternary < to you as well" - you can orchestratea < b < cfor your own type quite easily with the existing C++ language: you just havea < breturn a helper object (of a different type) that stores theboolresult AND the value ofbAND provides anoperator bool() constfor when justa < bis used, but if that helper object is compared with something else and the storedbis not< cit sets itsboolmember to false. So, the show-stopper is exclusively with being unable to implement it for built in types.
– Tony Delroy
Jun 10 at 12:51
3
You can. But if you ever feel the desire to actually do this, have a cold shower and wait for it to pass.
– jakub_d
Jun 10 at 12:57
By all means argue that if you like - I'm just pointing out that your current answer is wrong in saying some new ternary<would need to be exposed for use by user-defined types. (Though it may still make sense to expose a dedicated operator for efficiency reasons.)
– Tony Delroy
Jun 10 at 13:04
@TonyDelroy is it? OP is arguing that the behavior should be changed for a built-in type (int), introducing a new ternary<, I am saying that that change should propagate to user-defined types.
– jakub_d
Jun 10 at 13:11
If that makes sense to you, leave you answer as is. Cheers.
– Tony Delroy
Jun 10 at 14:02
add a comment |
C++ didn’t do it because that would have broken backward compatibility with C. So you would need to look another decade back for the answer.
I don’t know whether Brian Kernighan or Dennis Ritchie ever considered doing it the other way, or discussed their reasoning. I’m not aware of anyone requesting that specific feature. Their relational operators follow the same rules as other Algol-family languages.
One problem would have been that it makes the grammar ambiguous: 0 < x < 1 now has a very different meaning than (0 < x) < 1 or 0 < (x < 1). There are also the issue of how to parse a < b >= c or a < b == c. Remember, there was no Boolean type in K&R C. Logical operators returned int, since the result was presumed to be stored in a machine register.
Another possible reason behind it is that K&R C, according to its designers, is not a high-level language. Its basic operations generally correspond to machine instructions on the minicomputers it was developed on. So, a comparison was a machine instruction back then, and a double-comparison was not. It would’ve been strange, given the other choices they made, to introduce that particular syntactic sugar into the language just to make C code read a little more like a math paper.
add a comment |
Inside of if, there should be boolean condition. In 2 < x < 9, there are two conditions. And two conditions can't be calculated in C++ without operator between them. That's why we can't use 2 < x < 9.
add a comment |
6 Answers
6
active
oldest
votes
6 Answers
6
active
oldest
votes
active
oldest
votes
active
oldest
votes
The expression
2 < x < 9
is grouped as
(2 < x) < 9
And since 2 < x is either false (0) or true (1), and both are less than 9, it's always true.
So unless you use overloaded operators for a non-built-in type x (then a 3-way comparison would be possible if 2 < x were to return an instance of a proxy object on which < is defined), if you want to test if x is in the interval (2, 9) you need to write it the way you have.
5
So, that's not a three-way comparison.
– Lightness Races in Orbit
Jun 10 at 12:21
add a comment |
The expression
2 < x < 9
is grouped as
(2 < x) < 9
And since 2 < x is either false (0) or true (1), and both are less than 9, it's always true.
So unless you use overloaded operators for a non-built-in type x (then a 3-way comparison would be possible if 2 < x were to return an instance of a proxy object on which < is defined), if you want to test if x is in the interval (2, 9) you need to write it the way you have.
5
So, that's not a three-way comparison.
– Lightness Races in Orbit
Jun 10 at 12:21
add a comment |
The expression
2 < x < 9
is grouped as
(2 < x) < 9
And since 2 < x is either false (0) or true (1), and both are less than 9, it's always true.
So unless you use overloaded operators for a non-built-in type x (then a 3-way comparison would be possible if 2 < x were to return an instance of a proxy object on which < is defined), if you want to test if x is in the interval (2, 9) you need to write it the way you have.
The expression
2 < x < 9
is grouped as
(2 < x) < 9
And since 2 < x is either false (0) or true (1), and both are less than 9, it's always true.
So unless you use overloaded operators for a non-built-in type x (then a 3-way comparison would be possible if 2 < x were to return an instance of a proxy object on which < is defined), if you want to test if x is in the interval (2, 9) you need to write it the way you have.
edited Jun 10 at 12:32
answered Jun 10 at 12:20
BathshebaBathsheba
187k27268396
187k27268396
5
So, that's not a three-way comparison.
– Lightness Races in Orbit
Jun 10 at 12:21
add a comment |
5
So, that's not a three-way comparison.
– Lightness Races in Orbit
Jun 10 at 12:21
5
5
So, that's not a three-way comparison.
– Lightness Races in Orbit
Jun 10 at 12:21
So, that's not a three-way comparison.
– Lightness Races in Orbit
Jun 10 at 12:21
add a comment |
Just because this language doesn't have that feature.
It could have been made to, but this would contrast with C in a non-compatible way.
C could have been made to, but the designers simply didn't do that.
You already have the correct way to do it.
Some different (and newer!) languages do support this.
1
If contrasting with C was an issue, all C code would be compilable with a C++ compiler, which is not the case.
– Federico klez Culloca
Jun 10 at 12:24
16
@FedericoklezCulloca That's a bit of a fallacy. It is quite clear that the language designers have gone to great lengths to ensure a high level of compatibility with C. No, it's not a strict superset, but it's really, really close. Fundamentally changing the way operators work would be a big no-no.
– Lightness Races in Orbit
Jun 10 at 12:25
2
@FedericoklezCulloca C++ was explcitly designed to be mostly backwards compatibile with C. Of course there are places it couldn't be, but for basic syntax rules like this, the C way was maintained.
– NathanOliver
Jun 10 at 12:27
1
I doubt that any C programmer writes such code, because the result is nonsense. There was a proposal for this but it was rejected due to parsing issues in some compilers.
– Rakete1111
Jun 10 at 12:39
My favourite example:&and&&. Actually, it would have been much more comfortable in pure C++ if they opted for breaking the compatibility with C and had given the bitwise operator higher precedence than the comparison operators. This precedence as is dates back to the times the&&operator had not yet been invented in C. But if we drop this isolated view on C++, hell breaks loose faster than we even could ever measure...
– Aconcagua
Jun 10 at 12:47
|
show 2 more comments
Just because this language doesn't have that feature.
It could have been made to, but this would contrast with C in a non-compatible way.
C could have been made to, but the designers simply didn't do that.
You already have the correct way to do it.
Some different (and newer!) languages do support this.
1
If contrasting with C was an issue, all C code would be compilable with a C++ compiler, which is not the case.
– Federico klez Culloca
Jun 10 at 12:24
16
@FedericoklezCulloca That's a bit of a fallacy. It is quite clear that the language designers have gone to great lengths to ensure a high level of compatibility with C. No, it's not a strict superset, but it's really, really close. Fundamentally changing the way operators work would be a big no-no.
– Lightness Races in Orbit
Jun 10 at 12:25
2
@FedericoklezCulloca C++ was explcitly designed to be mostly backwards compatibile with C. Of course there are places it couldn't be, but for basic syntax rules like this, the C way was maintained.
– NathanOliver
Jun 10 at 12:27
1
I doubt that any C programmer writes such code, because the result is nonsense. There was a proposal for this but it was rejected due to parsing issues in some compilers.
– Rakete1111
Jun 10 at 12:39
My favourite example:&and&&. Actually, it would have been much more comfortable in pure C++ if they opted for breaking the compatibility with C and had given the bitwise operator higher precedence than the comparison operators. This precedence as is dates back to the times the&&operator had not yet been invented in C. But if we drop this isolated view on C++, hell breaks loose faster than we even could ever measure...
– Aconcagua
Jun 10 at 12:47
|
show 2 more comments
Just because this language doesn't have that feature.
It could have been made to, but this would contrast with C in a non-compatible way.
C could have been made to, but the designers simply didn't do that.
You already have the correct way to do it.
Some different (and newer!) languages do support this.
Just because this language doesn't have that feature.
It could have been made to, but this would contrast with C in a non-compatible way.
C could have been made to, but the designers simply didn't do that.
You already have the correct way to do it.
Some different (and newer!) languages do support this.
answered Jun 10 at 12:22
Lightness Races in OrbitLightness Races in Orbit
304k56491845
304k56491845
1
If contrasting with C was an issue, all C code would be compilable with a C++ compiler, which is not the case.
– Federico klez Culloca
Jun 10 at 12:24
16
@FedericoklezCulloca That's a bit of a fallacy. It is quite clear that the language designers have gone to great lengths to ensure a high level of compatibility with C. No, it's not a strict superset, but it's really, really close. Fundamentally changing the way operators work would be a big no-no.
– Lightness Races in Orbit
Jun 10 at 12:25
2
@FedericoklezCulloca C++ was explcitly designed to be mostly backwards compatibile with C. Of course there are places it couldn't be, but for basic syntax rules like this, the C way was maintained.
– NathanOliver
Jun 10 at 12:27
1
I doubt that any C programmer writes such code, because the result is nonsense. There was a proposal for this but it was rejected due to parsing issues in some compilers.
– Rakete1111
Jun 10 at 12:39
My favourite example:&and&&. Actually, it would have been much more comfortable in pure C++ if they opted for breaking the compatibility with C and had given the bitwise operator higher precedence than the comparison operators. This precedence as is dates back to the times the&&operator had not yet been invented in C. But if we drop this isolated view on C++, hell breaks loose faster than we even could ever measure...
– Aconcagua
Jun 10 at 12:47
|
show 2 more comments
1
If contrasting with C was an issue, all C code would be compilable with a C++ compiler, which is not the case.
– Federico klez Culloca
Jun 10 at 12:24
16
@FedericoklezCulloca That's a bit of a fallacy. It is quite clear that the language designers have gone to great lengths to ensure a high level of compatibility with C. No, it's not a strict superset, but it's really, really close. Fundamentally changing the way operators work would be a big no-no.
– Lightness Races in Orbit
Jun 10 at 12:25
2
@FedericoklezCulloca C++ was explcitly designed to be mostly backwards compatibile with C. Of course there are places it couldn't be, but for basic syntax rules like this, the C way was maintained.
– NathanOliver
Jun 10 at 12:27
1
I doubt that any C programmer writes such code, because the result is nonsense. There was a proposal for this but it was rejected due to parsing issues in some compilers.
– Rakete1111
Jun 10 at 12:39
My favourite example:&and&&. Actually, it would have been much more comfortable in pure C++ if they opted for breaking the compatibility with C and had given the bitwise operator higher precedence than the comparison operators. This precedence as is dates back to the times the&&operator had not yet been invented in C. But if we drop this isolated view on C++, hell breaks loose faster than we even could ever measure...
– Aconcagua
Jun 10 at 12:47
1
1
If contrasting with C was an issue, all C code would be compilable with a C++ compiler, which is not the case.
– Federico klez Culloca
Jun 10 at 12:24
If contrasting with C was an issue, all C code would be compilable with a C++ compiler, which is not the case.
– Federico klez Culloca
Jun 10 at 12:24
16
16
@FedericoklezCulloca That's a bit of a fallacy. It is quite clear that the language designers have gone to great lengths to ensure a high level of compatibility with C. No, it's not a strict superset, but it's really, really close. Fundamentally changing the way operators work would be a big no-no.
– Lightness Races in Orbit
Jun 10 at 12:25
@FedericoklezCulloca That's a bit of a fallacy. It is quite clear that the language designers have gone to great lengths to ensure a high level of compatibility with C. No, it's not a strict superset, but it's really, really close. Fundamentally changing the way operators work would be a big no-no.
– Lightness Races in Orbit
Jun 10 at 12:25
2
2
@FedericoklezCulloca C++ was explcitly designed to be mostly backwards compatibile with C. Of course there are places it couldn't be, but for basic syntax rules like this, the C way was maintained.
– NathanOliver
Jun 10 at 12:27
@FedericoklezCulloca C++ was explcitly designed to be mostly backwards compatibile with C. Of course there are places it couldn't be, but for basic syntax rules like this, the C way was maintained.
– NathanOliver
Jun 10 at 12:27
1
1
I doubt that any C programmer writes such code, because the result is nonsense. There was a proposal for this but it was rejected due to parsing issues in some compilers.
– Rakete1111
Jun 10 at 12:39
I doubt that any C programmer writes such code, because the result is nonsense. There was a proposal for this but it was rejected due to parsing issues in some compilers.
– Rakete1111
Jun 10 at 12:39
My favourite example:
& and &&. Actually, it would have been much more comfortable in pure C++ if they opted for breaking the compatibility with C and had given the bitwise operator higher precedence than the comparison operators. This precedence as is dates back to the times the && operator had not yet been invented in C. But if we drop this isolated view on C++, hell breaks loose faster than we even could ever measure...– Aconcagua
Jun 10 at 12:47
My favourite example:
& and &&. Actually, it would have been much more comfortable in pure C++ if they opted for breaking the compatibility with C and had given the bitwise operator higher precedence than the comparison operators. This precedence as is dates back to the times the && operator had not yet been invented in C. But if we drop this isolated view on C++, hell breaks loose faster than we even could ever measure...– Aconcagua
Jun 10 at 12:47
|
show 2 more comments
the comparison operators in c++ takes as an argument two values.
when you are writing a<b it is the same as operator<(a,b).
and the return value of operator< is bool.
when you are calling a function in c++, it is computing the expression of its arguments and then passing it to that function, so calling a<b<c is same asoperator<(operator<(a,b),c)
basically, the answer to your question is that in c++ there is no comparison operator (less than, greater than...) that takes three arguments
add a comment |
the comparison operators in c++ takes as an argument two values.
when you are writing a<b it is the same as operator<(a,b).
and the return value of operator< is bool.
when you are calling a function in c++, it is computing the expression of its arguments and then passing it to that function, so calling a<b<c is same asoperator<(operator<(a,b),c)
basically, the answer to your question is that in c++ there is no comparison operator (less than, greater than...) that takes three arguments
add a comment |
the comparison operators in c++ takes as an argument two values.
when you are writing a<b it is the same as operator<(a,b).
and the return value of operator< is bool.
when you are calling a function in c++, it is computing the expression of its arguments and then passing it to that function, so calling a<b<c is same asoperator<(operator<(a,b),c)
basically, the answer to your question is that in c++ there is no comparison operator (less than, greater than...) that takes three arguments
the comparison operators in c++ takes as an argument two values.
when you are writing a<b it is the same as operator<(a,b).
and the return value of operator< is bool.
when you are calling a function in c++, it is computing the expression of its arguments and then passing it to that function, so calling a<b<c is same asoperator<(operator<(a,b),c)
basically, the answer to your question is that in c++ there is no comparison operator (less than, greater than...) that takes three arguments
answered Jun 10 at 12:29
zapredelomzapredelom
5421324
5421324
add a comment |
add a comment |
If C++ chose to redefine a < b < c to better align with the mathematical notation, it would be ambiguous with the current meaning. The current meaning is a bit silly and is comparing bools with numbers, but there may be tricky code relying on this detail in production use.
And as C++ allows you to define your own types with operators, it would have to expose the new ternary < to you as well, so you could make one for your type. Which would open new cans of worms if you only define a binary < but no ternary < for your type - should the compiler start shouting at you?
1
"your own types with operators, it would have to expose the new ternary < to you as well" - you can orchestratea < b < cfor your own type quite easily with the existing C++ language: you just havea < breturn a helper object (of a different type) that stores theboolresult AND the value ofbAND provides anoperator bool() constfor when justa < bis used, but if that helper object is compared with something else and the storedbis not< cit sets itsboolmember to false. So, the show-stopper is exclusively with being unable to implement it for built in types.
– Tony Delroy
Jun 10 at 12:51
3
You can. But if you ever feel the desire to actually do this, have a cold shower and wait for it to pass.
– jakub_d
Jun 10 at 12:57
By all means argue that if you like - I'm just pointing out that your current answer is wrong in saying some new ternary<would need to be exposed for use by user-defined types. (Though it may still make sense to expose a dedicated operator for efficiency reasons.)
– Tony Delroy
Jun 10 at 13:04
@TonyDelroy is it? OP is arguing that the behavior should be changed for a built-in type (int), introducing a new ternary<, I am saying that that change should propagate to user-defined types.
– jakub_d
Jun 10 at 13:11
If that makes sense to you, leave you answer as is. Cheers.
– Tony Delroy
Jun 10 at 14:02
add a comment |
If C++ chose to redefine a < b < c to better align with the mathematical notation, it would be ambiguous with the current meaning. The current meaning is a bit silly and is comparing bools with numbers, but there may be tricky code relying on this detail in production use.
And as C++ allows you to define your own types with operators, it would have to expose the new ternary < to you as well, so you could make one for your type. Which would open new cans of worms if you only define a binary < but no ternary < for your type - should the compiler start shouting at you?
1
"your own types with operators, it would have to expose the new ternary < to you as well" - you can orchestratea < b < cfor your own type quite easily with the existing C++ language: you just havea < breturn a helper object (of a different type) that stores theboolresult AND the value ofbAND provides anoperator bool() constfor when justa < bis used, but if that helper object is compared with something else and the storedbis not< cit sets itsboolmember to false. So, the show-stopper is exclusively with being unable to implement it for built in types.
– Tony Delroy
Jun 10 at 12:51
3
You can. But if you ever feel the desire to actually do this, have a cold shower and wait for it to pass.
– jakub_d
Jun 10 at 12:57
By all means argue that if you like - I'm just pointing out that your current answer is wrong in saying some new ternary<would need to be exposed for use by user-defined types. (Though it may still make sense to expose a dedicated operator for efficiency reasons.)
– Tony Delroy
Jun 10 at 13:04
@TonyDelroy is it? OP is arguing that the behavior should be changed for a built-in type (int), introducing a new ternary<, I am saying that that change should propagate to user-defined types.
– jakub_d
Jun 10 at 13:11
If that makes sense to you, leave you answer as is. Cheers.
– Tony Delroy
Jun 10 at 14:02
add a comment |
If C++ chose to redefine a < b < c to better align with the mathematical notation, it would be ambiguous with the current meaning. The current meaning is a bit silly and is comparing bools with numbers, but there may be tricky code relying on this detail in production use.
And as C++ allows you to define your own types with operators, it would have to expose the new ternary < to you as well, so you could make one for your type. Which would open new cans of worms if you only define a binary < but no ternary < for your type - should the compiler start shouting at you?
If C++ chose to redefine a < b < c to better align with the mathematical notation, it would be ambiguous with the current meaning. The current meaning is a bit silly and is comparing bools with numbers, but there may be tricky code relying on this detail in production use.
And as C++ allows you to define your own types with operators, it would have to expose the new ternary < to you as well, so you could make one for your type. Which would open new cans of worms if you only define a binary < but no ternary < for your type - should the compiler start shouting at you?
answered Jun 10 at 12:33
jakub_djakub_d
1,316213
1,316213
1
"your own types with operators, it would have to expose the new ternary < to you as well" - you can orchestratea < b < cfor your own type quite easily with the existing C++ language: you just havea < breturn a helper object (of a different type) that stores theboolresult AND the value ofbAND provides anoperator bool() constfor when justa < bis used, but if that helper object is compared with something else and the storedbis not< cit sets itsboolmember to false. So, the show-stopper is exclusively with being unable to implement it for built in types.
– Tony Delroy
Jun 10 at 12:51
3
You can. But if you ever feel the desire to actually do this, have a cold shower and wait for it to pass.
– jakub_d
Jun 10 at 12:57
By all means argue that if you like - I'm just pointing out that your current answer is wrong in saying some new ternary<would need to be exposed for use by user-defined types. (Though it may still make sense to expose a dedicated operator for efficiency reasons.)
– Tony Delroy
Jun 10 at 13:04
@TonyDelroy is it? OP is arguing that the behavior should be changed for a built-in type (int), introducing a new ternary<, I am saying that that change should propagate to user-defined types.
– jakub_d
Jun 10 at 13:11
If that makes sense to you, leave you answer as is. Cheers.
– Tony Delroy
Jun 10 at 14:02
add a comment |
1
"your own types with operators, it would have to expose the new ternary < to you as well" - you can orchestratea < b < cfor your own type quite easily with the existing C++ language: you just havea < breturn a helper object (of a different type) that stores theboolresult AND the value ofbAND provides anoperator bool() constfor when justa < bis used, but if that helper object is compared with something else and the storedbis not< cit sets itsboolmember to false. So, the show-stopper is exclusively with being unable to implement it for built in types.
– Tony Delroy
Jun 10 at 12:51
3
You can. But if you ever feel the desire to actually do this, have a cold shower and wait for it to pass.
– jakub_d
Jun 10 at 12:57
By all means argue that if you like - I'm just pointing out that your current answer is wrong in saying some new ternary<would need to be exposed for use by user-defined types. (Though it may still make sense to expose a dedicated operator for efficiency reasons.)
– Tony Delroy
Jun 10 at 13:04
@TonyDelroy is it? OP is arguing that the behavior should be changed for a built-in type (int), introducing a new ternary<, I am saying that that change should propagate to user-defined types.
– jakub_d
Jun 10 at 13:11
If that makes sense to you, leave you answer as is. Cheers.
– Tony Delroy
Jun 10 at 14:02
1
1
"your own types with operators, it would have to expose the new ternary < to you as well" - you can orchestrate
a < b < c for your own type quite easily with the existing C++ language: you just have a < b return a helper object (of a different type) that stores the bool result AND the value of b AND provides an operator bool() const for when just a < b is used, but if that helper object is compared with something else and the stored b is not < c it sets its bool member to false. So, the show-stopper is exclusively with being unable to implement it for built in types.– Tony Delroy
Jun 10 at 12:51
"your own types with operators, it would have to expose the new ternary < to you as well" - you can orchestrate
a < b < c for your own type quite easily with the existing C++ language: you just have a < b return a helper object (of a different type) that stores the bool result AND the value of b AND provides an operator bool() const for when just a < b is used, but if that helper object is compared with something else and the stored b is not < c it sets its bool member to false. So, the show-stopper is exclusively with being unable to implement it for built in types.– Tony Delroy
Jun 10 at 12:51
3
3
You can. But if you ever feel the desire to actually do this, have a cold shower and wait for it to pass.
– jakub_d
Jun 10 at 12:57
You can. But if you ever feel the desire to actually do this, have a cold shower and wait for it to pass.
– jakub_d
Jun 10 at 12:57
By all means argue that if you like - I'm just pointing out that your current answer is wrong in saying some new ternary
< would need to be exposed for use by user-defined types. (Though it may still make sense to expose a dedicated operator for efficiency reasons.)– Tony Delroy
Jun 10 at 13:04
By all means argue that if you like - I'm just pointing out that your current answer is wrong in saying some new ternary
< would need to be exposed for use by user-defined types. (Though it may still make sense to expose a dedicated operator for efficiency reasons.)– Tony Delroy
Jun 10 at 13:04
@TonyDelroy is it? OP is arguing that the behavior should be changed for a built-in type (int), introducing a new ternary
<, I am saying that that change should propagate to user-defined types.– jakub_d
Jun 10 at 13:11
@TonyDelroy is it? OP is arguing that the behavior should be changed for a built-in type (int), introducing a new ternary
<, I am saying that that change should propagate to user-defined types.– jakub_d
Jun 10 at 13:11
If that makes sense to you, leave you answer as is. Cheers.
– Tony Delroy
Jun 10 at 14:02
If that makes sense to you, leave you answer as is. Cheers.
– Tony Delroy
Jun 10 at 14:02
add a comment |
C++ didn’t do it because that would have broken backward compatibility with C. So you would need to look another decade back for the answer.
I don’t know whether Brian Kernighan or Dennis Ritchie ever considered doing it the other way, or discussed their reasoning. I’m not aware of anyone requesting that specific feature. Their relational operators follow the same rules as other Algol-family languages.
One problem would have been that it makes the grammar ambiguous: 0 < x < 1 now has a very different meaning than (0 < x) < 1 or 0 < (x < 1). There are also the issue of how to parse a < b >= c or a < b == c. Remember, there was no Boolean type in K&R C. Logical operators returned int, since the result was presumed to be stored in a machine register.
Another possible reason behind it is that K&R C, according to its designers, is not a high-level language. Its basic operations generally correspond to machine instructions on the minicomputers it was developed on. So, a comparison was a machine instruction back then, and a double-comparison was not. It would’ve been strange, given the other choices they made, to introduce that particular syntactic sugar into the language just to make C code read a little more like a math paper.
add a comment |
C++ didn’t do it because that would have broken backward compatibility with C. So you would need to look another decade back for the answer.
I don’t know whether Brian Kernighan or Dennis Ritchie ever considered doing it the other way, or discussed their reasoning. I’m not aware of anyone requesting that specific feature. Their relational operators follow the same rules as other Algol-family languages.
One problem would have been that it makes the grammar ambiguous: 0 < x < 1 now has a very different meaning than (0 < x) < 1 or 0 < (x < 1). There are also the issue of how to parse a < b >= c or a < b == c. Remember, there was no Boolean type in K&R C. Logical operators returned int, since the result was presumed to be stored in a machine register.
Another possible reason behind it is that K&R C, according to its designers, is not a high-level language. Its basic operations generally correspond to machine instructions on the minicomputers it was developed on. So, a comparison was a machine instruction back then, and a double-comparison was not. It would’ve been strange, given the other choices they made, to introduce that particular syntactic sugar into the language just to make C code read a little more like a math paper.
add a comment |
C++ didn’t do it because that would have broken backward compatibility with C. So you would need to look another decade back for the answer.
I don’t know whether Brian Kernighan or Dennis Ritchie ever considered doing it the other way, or discussed their reasoning. I’m not aware of anyone requesting that specific feature. Their relational operators follow the same rules as other Algol-family languages.
One problem would have been that it makes the grammar ambiguous: 0 < x < 1 now has a very different meaning than (0 < x) < 1 or 0 < (x < 1). There are also the issue of how to parse a < b >= c or a < b == c. Remember, there was no Boolean type in K&R C. Logical operators returned int, since the result was presumed to be stored in a machine register.
Another possible reason behind it is that K&R C, according to its designers, is not a high-level language. Its basic operations generally correspond to machine instructions on the minicomputers it was developed on. So, a comparison was a machine instruction back then, and a double-comparison was not. It would’ve been strange, given the other choices they made, to introduce that particular syntactic sugar into the language just to make C code read a little more like a math paper.
C++ didn’t do it because that would have broken backward compatibility with C. So you would need to look another decade back for the answer.
I don’t know whether Brian Kernighan or Dennis Ritchie ever considered doing it the other way, or discussed their reasoning. I’m not aware of anyone requesting that specific feature. Their relational operators follow the same rules as other Algol-family languages.
One problem would have been that it makes the grammar ambiguous: 0 < x < 1 now has a very different meaning than (0 < x) < 1 or 0 < (x < 1). There are also the issue of how to parse a < b >= c or a < b == c. Remember, there was no Boolean type in K&R C. Logical operators returned int, since the result was presumed to be stored in a machine register.
Another possible reason behind it is that K&R C, according to its designers, is not a high-level language. Its basic operations generally correspond to machine instructions on the minicomputers it was developed on. So, a comparison was a machine instruction back then, and a double-comparison was not. It would’ve been strange, given the other choices they made, to introduce that particular syntactic sugar into the language just to make C code read a little more like a math paper.
edited Jun 11 at 1:08
answered Jun 10 at 23:43
DavislorDavislor
9,62021529
9,62021529
add a comment |
add a comment |
Inside of if, there should be boolean condition. In 2 < x < 9, there are two conditions. And two conditions can't be calculated in C++ without operator between them. That's why we can't use 2 < x < 9.
add a comment |
Inside of if, there should be boolean condition. In 2 < x < 9, there are two conditions. And two conditions can't be calculated in C++ without operator between them. That's why we can't use 2 < x < 9.
add a comment |
Inside of if, there should be boolean condition. In 2 < x < 9, there are two conditions. And two conditions can't be calculated in C++ without operator between them. That's why we can't use 2 < x < 9.
Inside of if, there should be boolean condition. In 2 < x < 9, there are two conditions. And two conditions can't be calculated in C++ without operator between them. That's why we can't use 2 < x < 9.
answered Jun 10 at 12:23
Faruk HossainFaruk Hossain
2796
2796
add a comment |
add a comment |
9
Because e.g.
2 < 10 < 9will be interpreted as(2 < 10) < 9, that is1 < 9which is true– Federico klez Culloca
Jun 10 at 12:20
3
Because the compiler is processing the operators from left to right and with precedence in mind.
2 < 10 < 9is therefore processed as(2 < 10) < 9, from which we get1 < 9as 2 is less then 10 results intotruewhich is interpreted as 1.– Anže
Jun 10 at 12:21
5
This notation makes a lot of sense in mathematical text but is hard to consistently capture with a parser, without confusing parsing rules. In particular, '>' would no longer be a binary operator that applies directly to its left hand and right hand neighbors, and parsers would have to look in a larger context window for meaning.
– jwimberley
Jun 10 at 12:21
10
Nitpicking about terminology, in the upcoming C++20 standard there will come a three-way comparison operator. But it doesn't do what you want either, so please be careful when using that term.
– Some programmer dude
Jun 10 at 12:24
6
The only language I'm aware that has such a comparison is Python, where
a op1 b op2 cis just syntactic sugar fora op1 b and b op2 c. (So Python also allows weird things like2 < 3 != 1(which is true) and1 < 2 in [3,4,5](which is false).)– molbdnilo
Jun 10 at 12:32