3 ms·
Was there ever a reason given as to why “explicit” was chosen over a hypothetical “implicit”?
by jimbob45 2y ago
Was there ever a reason given as to why “explicit” was chosen over a hypothetical “implicit”?
- RcouF1uZ4gsC 2y agoIn C++ because of how it developed the defaults are not optimal. For example, constructors and conversions are implicit and you have to make them explicit. Variables are default mutable and you have to make them const. Local primitive variables are default unitialized by default.
- JTyQZSnP3cQGa8B 2y ago> Variables are default mutable and you have to make them const Except for the captured variables in a lambda which are const unless you use the mutable keyword. Not a bad idea though.
- Maxatar 2y agoAnd that's only true if you capture by value. If you capture by reference they remain mutable.
- chombier 2y agoI think this is because `mutable` qualifies the call operator of the lambda (like a reverse const qualifier) so by-value captures are effectively const during the call unless the lambda is marked `mutable`. References themselves are always const, but the referenced object may be modified through the reference depending on its constness even though the lambda is not `mutable`. Is there a way to force capture by const-reference by the way?
- gpderetta 2y agoint main() { int x = 0; [&x] { x= 1;}(); // works [&x=std::as_const(x)] { x= 1;}(); // error: assignment of read-only reference 'x' } Not very pretty, but it works.
- cjensen 2y agoI don't know, but a hypothetical 'implicit' would mean converting all unmarked constructors into explicit constructors... which would have broken a lot of existing code.
- pjmlp 2y agoMany of the original C++ decisions come back to how it was supposed to be Typescript for C, which was a reason why it became widely used, and why some warts are the way they are. Like having C structs magically turn into C++ ones, thus implicit rules like these. Anyone that cares about C++ evolution should read "Design and Evolution of C++", not only for how it came to be, also for safety approaches over plain C, that Bjarne is stil arguing for to this day on WG21 meetings.
- senkora 2y agoI don't understand. When does a C89 struct display implicit conversion behavior that would justify making C++ class constructors implicit by-default? For example, the following code does not compile with either -std=c89 or -std=c++98, but does compile if we uncomment the constructor line: struct Foo { int x; /*public: Foo(int x) : x(x) {}*/ }; int main() { struct Foo foo = 5; return 0; } $ gcc -std=c89 tmp.c tmp.c: In function ‘main’: tmp.c:8:20: error: invalid initializer 8 | struct Foo foo = 5; | ^ $ g++ -std=c++98 tmp.c tmp.c: In function ‘int main()’: tmp.c:8:20: error: conversion from ‘int’ to non-scalar type ‘Foo’ requested 8 | struct Foo foo = 5; Maybe I'm missing something?
- pjmlp 2y agoYou are missing that such struct initialization did not exist when C with Classes came to be. Additionally, you are missing the whole package of struct semantics in C++, that while they should at naked eye still look like C structs, they have to also support C++ struct semantics, of memory construction, copy assignment and bitwise comparisaion. Hence why structs and classes are the same, with the difference that structs are public by default, with code generated for keeping the bitwise C semantics, until any of those operations are redifined, at which point the compiler leaves out the job to the developer.
- senkora 2y agoThank you for the response. I still don’t understand why it would be necessary for C++ to default to non-explicit constructors when C at the time did not have constructors and did not have constructor-like struct initialization that mimicked non-explicit constructors. It seems like an unforced error in the language design, rather than a concession to backwards-compatibility.
- lenkite 2y agoI guess if Stroustrup had made "explicit" constructors the default, the C-graybeards would never have adopted C++. Far too much work in porting.