Consider this program:
#include <iostream>
using std::cout;
using std::endl;
struct C {
int x;
C(int _x) : x(_x) {}
operator bool() const { return 0 != x; }
};
struct D {
float f;
D(float _f) : f(_f) {}
operator bool() const { return 0.0f != f; }
};
int main() {
C c(9);
D d(2.0f);
if (c == d) {
cout << "Equal" << endl;
}
return 0;
}
g++ 3.4.4 doesn't so much as warn that something is fishy here, even with -Wall.Not only that, but c and d are considered to be equal.
I don't have a C++0x compiler handy, or I would test it, but I do believe explicit is only meant for cases such as this:
a + 1;
where a has a bool() operator that returns 1 or 0, in the old mode if there was no way to get a to be a number it would look at the operator bool() see that it returns a number and use that. Using explicit on the bool() operator would make that illegal and most likely a compiler error.
c.bool() == d.bool()
In this case both will return true since they are non-zero, and thus the statement would be
1 == 1
Which is true; the compiler did exactly as you told it to do.
Are you saying that the funtion YOU wrote to convert C/D to a bool shouldn't be invoked when YOU are using C/D as booleans?
But it's confusing that they're being used as booleans at all. They're converted because it will let the types match even though the conversion doesn't make much sense.
I know I'm flinging links around a lot here, but, well, this is all well-covered ground.
The bitching about bad compile time errors has been mostly fixed in clang.
Then only _inconsistency_ (in the correct sense of the term) in C++ I am aware of is the unordered initialization of static objects. So if you have "class A { ... A () { } };" and have a "A foo;" declared somewhere with static linkage, it can be hard to pin down exactly _when_ that constructor will be called. It will be called before control is transferred to main, but you may want even finer control.
If you have noticed other inconsistencies I'd love to know.
Yes, IOW, it is a compiler problem, not a language problem. Because one particular compiler is horrible on error presentation doesn't mean that the language is bad.
> declared somewhere with static linkage, it can be hard to pin down exactly _when_ that constructor will be called.
The language doesn't define it on purpose. The language leaves it to be defined by the implementation because it goes a little beyond the purpose of the compiler. The compiler transforms C++ source into object code. You can have multiple objects linked together into a single binary, and this linkage is very platform and operating-system dependent. C++ is already horribly difficult to implement correctly; if the language were to define an order for static initialization, it would be stepping on the operating system domain, and make it even more difficult to implement on some systems.
another provblem arises due to the decoration, mangling of c++ symbols (while c externs do not have this problem), and sometimes this is problem even with two different versions of the same line of compiler
another one is the runtime incompabilities (exceptions again) and different compilers.
this problem is so bitchy, that if you have to develop plugin for maya, motion builder in c++, you have to use the same compiler the products were compiled with, which is not the case for a lot of the infrastructure, os out there...