[type traits] Strange behaviour of comparison operators with pointers

The following code gives a compile time error (g++ and msvc): int const lhs=1; int* rhs=0; lhs == rhs; But the following code gives no error: int const lhs=0; int* rhs=0; lhs == rhs; because a const int with 0 value is a valid null pointer! Then there is no way to predict if it is possible to compare lhs and rhs based only on their types. The general rule is that it is not possible so that this is what I propose to use for the type trait extension detecting the possibility to call comparison operators on given types. Frédéric

On 6/18/2011 6:23 AM, Frédéric Bron wrote:
The following code gives a compile time error (g++ and msvc): int const lhs=1; int* rhs=0; lhs == rhs;
Expected.
But the following code gives no error: int const lhs=0; int* rhs=0; lhs == rhs; because a const int with 0 value is a valid null pointer!
Or you could say: 0 == rhs which is valid.
Then there is no way to predict if it is possible to compare lhs and rhs based only on their types.
Why do you write this ? Just because 0 can be an integer or a null pointer in C++ does not mean the above.
The general rule is that it is not possible so that this is what I propose to use for the type trait extension detecting the possibility to call comparison operators on given types.
To what does "this" refer in your previous sentence ?

Then there is no way to predict if it is possible to compare lhs and rhs based only on their types.
Why do you write this ? Just because 0 can be an integer or a null pointer in C++ does not mean the above.
Here it is not literal 0 that can be an integer or a null pointer it is an const integer of value 0 that can also be considered as a null pointer... It seems to me that it makes a difference. If I tell you can you compare "int const" with "int*", you would probably answer "no" but if the "int const" is 0 the answer is false.
The general rule is that it is not possible so that this is what I propose to use for the type trait extension detecting the possibility to call comparison operators on given types.
To what does "this" refer in your previous sentence ?
I mean that I propose can_call_equal (or whatever name...) < int const, int * >::value to be false even if there is a possibility for comparing some int const with int*. Frédéric

2011/6/18 Frédéric Bron <frederic.bron@m4x.org>
Then there is no way to predict if it is possible to compare lhs and rhs based only on their types.
Why do you write this ? Just because 0 can be an integer or a null pointer in C++ does not mean the above.
Here it is not literal 0 that can be an integer or a null pointer it is an const integer of value 0 that can also be considered as a null pointer... It seems to me that it makes a difference. If I tell you can you compare "int const" with "int*", you would probably answer "no" but if the "int const" is 0 the answer is false.
The general rule is that it is not possible so that this is what I propose to use for the type trait extension detecting the possibility to call comparison operators on given types.
To what does "this" refer in your previous sentence ?
I mean that I propose can_call_equal (or whatever name...) < int const, int * >::value to be false even if there is a possibility for comparing some int const with int*.
I think of these operator type traits as specifically answering the query "Is make<T>() [op] make<U>() a compilable (syntactically well-formed?) expression?" with template< class T > T make(); which is consistent with your proposition; i.e., I agree. - Jeff

Jeffrey Lee Hellrung, Jr. wrote:
2011/6/18 Frédéric Bron <frederic.bron@m4x.org>
I mean that I propose can_call_equal (or whatever name...) <int const, int * >::value to be false even if there is a possibility for comparing some int const with int*.
I think of these operator type traits as specifically answering the query
"Is make<T>() [op] make<U>() a compilable (syntactically well- formed?) expression?"
with
template< class T > T make();
which is consistent with your proposition; i.e., I agree.
+1 _____ Rob Stewart robert.stewart@sig.com Software Engineer using std::disclaimer; Dev Tools & Components Susquehanna International Group, LLP http://www.sig.com IMPORTANT: The information contained in this email and/or its attachments is confidential. If you are not the intended recipient, please notify the sender immediately by reply and immediately delete this message and all its attachments. Any review, use, reproduction, disclosure or dissemination of this message or any attachment by an unintended recipient is strictly prohibited. Neither this message nor any attachment is intended as or should be construed as an offer, solicitation or recommendation to buy or sell any security or other financial instrument. Neither the sender, his or her employer nor any of their respective affiliates makes any warranties as to the completeness or accuracy of any of the information contained herein or that this message or any of its attachments is free of viruses.

On 6/18/2011 8:02 AM, Frédéric Bron wrote:
Then there is no way to predict if it is possible to compare lhs and rhs based only on their types.
Why do you write this ? Just because 0 can be an integer or a null pointer in C++ does not mean the above.
Here it is not literal 0 that can be an integer or a null pointer it is an const integer of value 0 that can also be considered as a null pointer... It seems to me that it makes a difference. If I tell you can you compare "int const" with "int*", you would probably answer "no" but if the "int const" is 0 the answer is false.
I understand that.
The general rule is that it is not possible so that this is what I propose to use for the type trait extension detecting the possibility to call comparison operators on given types.
To what does "this" refer in your previous sentence ?
I mean that I propose can_call_equal (or whatever name...)< int const, int *>::value to be false even if there is a possibility for comparing some int const with int*.
I agree with that. Initially you sounded like you would not handle 'pointer == const int' at all, and it was that to which I was objecting. However I was thinking... Is it not possible to test for const int x being 0 at compile time, possibly with MPL equal_to ? Then you could handle the case where the "int const" is 0, returning true when that is the case, otherwise returning false. In the MPL docs it says: "An integral constant object is implicitly convertible to the corresponding run-time value of the wrapped integral type." In your case the "int const x" is an integral constant object.

However I was thinking... Is it not possible to test for const int x being 0 at compile time, possibly with MPL equal_to ? Then you could handle the case where the "int const" is 0, returning true when that is the case, otherwise returning false.
In fact, if it is an "integral constant expression", the answer is yes. But if not, I suspect the code would yield a compile time error. But the arguments of the trait are types not linked to any value. Then it seems to me that it is impossible. Frédéric

On 6/21/2011 12:57 AM, Frédéric Bron wrote:
However I was thinking... Is it not possible to test for const int x being 0 at compile time, possibly with MPL equal_to ? Then you could handle the case where the "int const" is 0, returning true when that is the case, otherwise returning false.
In fact, if it is an "integral constant expression", the answer is yes. But if not, I suspect the code would yield a compile time error.
One could always check first at compile time with is_same.
But the arguments of the trait are types not linked to any value.
Yes, of course. Sorry for the noise. It is clearly up to the user of your operators to look at a value if available. But thanks for bringing up a good point.
Then it seems to me that it is impossible.
participants (4)
-
Edward Diener
-
Frédéric Bron
-
Jeffrey Lee Hellrung, Jr.
-
Stewart, Robert