News for hackers. Stuff that matters.
Re:How the STL Uses Explicit by jimbob45 on Wednesday June 26, 2024 @08:46PM (#40806193)
Was there ever a reason given as to why “explicit” was chosen over a hypothetical “implicit”?
Re:How the STL Uses Explicit by cjensen on Wednesday June 26, 2024 @10:58PM (#40806782)
I 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.
Re:How the STL Uses Explicit by RcouF1uZ4gsC on Wednesday June 26, 2024 @09:17PM (#40806363)
In 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.
Re:How the STL Uses Explicit by JTyQZSnP3cQGa8B on Wednesday June 26, 2024 @09:49PM (#40806501)
> 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.

Re:How the STL Uses Explicit by Maxatar on Wednesday June 26, 2024 @10:21PM (#40806618)
And that's only true if you capture by value. If you capture by reference they remain mutable.
Re:How the STL Uses Explicit by chombier on Thursday June 27, 2024 @01:18AM (#40807493)
I 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?

Re:How the STL Uses Explicit by gpderetta on Thursday June 27, 2024 @04:55AM (#40808639)

  int 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.
Re:How the STL Uses Explicit by pjmlp on Thursday June 27, 2024 @03:39AM (#40808290)
Many 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.

Re:How the STL Uses Explicit by senkora on Thursday June 27, 2024 @07:58AM (#40809544)
I 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?
Re:How the STL Uses Explicit by pjmlp on Thursday June 27, 2024 @11:15AM (#40811463)
You 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.

Re:How the STL Uses Explicit by senkora on Thursday June 27, 2024 @02:17PM (#40813403)
Thank 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.

Re:How the STL Uses Explicit by lenkite on Thursday June 27, 2024 @07:20AM (#40809290)
I guess if Stroustrup had made "explicit" constructors the default, the C-graybeards would never have adopted C++. Far too much work in porting.
Re:How the STL Uses Explicit by geerlingguy on Wednesday June 26, 2024 @09:32PM (#40806425)
STL is overloaded - it seems like St. Louis is mentioned, but this has to do with the Standard Template Library? And there's Studio-Transmitter Links in radio and 3D .stl files...

Edit: After searching the event name, it looks like it's a C++ standards convention that's meeting in St. Louis / STL (MO, USA) this week, and one of the topics of discussion is the C++ STL (Standard Template Library).

Re:How the STL Uses Explicit by seanhunter on Thursday June 27, 2024 @01:00AM (#40807407)
Even if you think STL means St Louis, you can't make that sentence confusing becasue none of those other potential uses work in this place.

eg "The St Louis" is only a possible construction if you put another noun after it like "How the STL cardinals handle the pressure of big games" (I don't know, I don't really do sports but you get the idea that's a valid sentence).

You can't have a sentence "How the STL uses explicit" be at all confusing with any of the examples you gave.

Re:How the STL Uses Explicit by saghm on Thursday June 27, 2024 @02:18AM (#40807819)
At least grammatically "the St. Louis" could make sense if you read it as referring to the namesake of the city. "Who was that guy using explicit contstructors, King Louis XIV?" "No, it was the _Saint_ Louis!"

I assume that no one named Louis has been canonized since C++ was invented though, and even if it was, using "the" might not be enough to disambiguate in some contexts.

Re:How the STL Uses Explicit by seanhunter on Thursday June 27, 2024 @03:09AM (#40808117)
...but do we know how the Saint Louis uses explicit? Catholic would-be C++ experts are dying to know.
Re:How the STL Uses Explicit by saghm on Thursday June 27, 2024 @03:01PM (#40813845)
There's probably no way of knowing, unfortunately; when the meek inherit the earth, they don't have access to the constructors of the parent class.
Re:How the STL Uses Explicit by tialaramex on Thursday June 27, 2024 @04:45AM (#40808591)
I feel like you're obliged to omit "Louis" here? Certainly I would feel I can't add this superfluous word, whereas in some cases such words are optional I don't think one is here.

I can say "No, it was the Saint" and "No, it was Saint Louis" but I don't think I'd utter "No, it was the Saint Louis" except as a speech error, maybe prompted by rushing like a Colemanball (commonly sports commentators mix metaphors or change their minds about intent midway through an utterance as of course they're live and events are unfolding as they speak, e.g. "That was a decisive mistake although nothing is decided yet").

Re:How the STL Uses Explicit by saghm on Thursday June 27, 2024 @02:56PM (#40813790)
> I can say "No, it was the Saint" and "No, it was Saint Louis" but I don't think I'd utter "No, it was the Saint Louis" except as a speech error

I don't think you're wrong per se, but this seems more like a personal style of speaking rather than a matter of correctness; some people might prefer conciseness, whereas others might speak more formally and avoid any implicitness. I think it also can feel quite a bit different depending on how the words are emphasized; I italicized "the" in my previous comment since it was the word being questioned, but it doesn't feel super jarring to me to add "the" when "Saint" is emphasized in your quote above. I can totally imagine myself or someone else being confused for a bit and after in the relief of finally understanding dragging out the words a bit like "ohhhhh, it was the _Saint_ Louis, I thought you meant the _other_ one".

Re:How the STL Uses Explicit by _old_dude_ on Thursday June 27, 2024 @04:49AM (#40808610)
BTW, Saint Louis is the common name of Louis IX not Louis XIV (the Sun King).

https://en.wikipedia.org/wiki/Louis_IX_of_France

Re:How the STL Uses Explicit by saghm on Thursday June 27, 2024 @11:04AM (#40811323)
Interesting, I didn't even realize that Saint Louis was one of the French kings; I guess I got lucky I didn't accidentally pick the same one twice!
Re:How the STL Uses Explicit by geerlingguy on Thursday June 27, 2024 @08:12AM (#40809633)
Most people from St. Louis are used to hearing the phrasings "the STL", or "the Lou" when referring to the city.
Re:How the STL Uses Explicit by account42 on Thursday June 27, 2024 @04:13AM (#40808439)
The C++ standard library isn't even officially called the STL - that name just carried over from the SGI STL [0] that inspired some of it.

[0] https://www.boost.org/sgi/stl/ (archive)

Re:How the STL Uses Explicit by 3836293648 on Thursday June 27, 2024 @05:55AM (#40808890)
Isn't the msvc implementation called the stl?

https://github.com/microsoft/STL

Re:How the STL Uses Explicit by metadat on Thursday June 27, 2024 @12:46AM (#40807313)
How can the C++ statement below even compile? Since "1" and "2" are strings (not even chars).

  std::vector<int> v = {"1", "2"} // UB
Rather than undefined behavior I'd expect a type violation error. But my C++ has gotten a bit rusty.
Re:How the STL Uses Explicit by GrantMoyer on Thursday June 27, 2024 @01:30AM (#40807551)
It's simple: "string" literals in C++ are pointers to characters. std::vector has a constructor which takes a begin and end iterator and creates a vector with contents copied from that range. Pointers are iterators in C++, and chars are implicitly convertible to ints, so overload resolution selects the aforementioned constructor. The pointer to "1" and the pointer to "2" don't point into the same object, so trying to iterate from one to the other eventually causes a dereference past the end of "1" which is undefined behavior.
Re:How the STL Uses Explicit by metadat on Thursday June 27, 2024 @01:41AM (#40807616)
I don't know about simple, haha, but thank you so much for explaining in depth!
Re:How the STL Uses Explicit by jiggawatts on Thursday June 27, 2024 @05:44AM (#40808847)
This... this is why I gave up C++ programming and have not looked back.
Re:How the STL Uses Explicit by lionkor on Thursday June 27, 2024 @06:16AM (#40808980)
Good! More UB for the rest of us!
Re:How the STL Uses Explicit by WJW on Thursday June 27, 2024 @06:21AM (#40809003)
Now now gentlemen, play nice. There is enough UB for all of us :)
Re:How the STL Uses Explicit by ralferoo on Friday June 28, 2024 @06:00AM (#40819161)
All UBs are belong to us!
Re:How the STL Uses Explicit by saagarjha on Saturday June 29, 2024 @03:50AM (#40828574)
Nah, C holds claim to some of it
Re:How the STL Uses Explicit by mwkaufma on Thursday June 27, 2024 @01:31AM (#40807556)
It's matching std::vector's implicit constructor which takes two iterators, which can be initialized with any pointer. Note that it won't compile with one, three, or more string-literal char*s, but exactly two.
Re:How the STL Uses Explicit by metadat on Thursday June 27, 2024 @01:39AM (#40807605)
Why only exactly two?

The whole "UB but it still compiles" thing, is pretty gross.

Re:How the STL Uses Explicit by comex on Thursday June 27, 2024 @02:10AM (#40807773)
Because the constructor takes two arguments, a "begin" iterator and an "end" iterator. And pointers count as valid iterators.

Normally you wouldn't use the "= {}" syntax to invoke a constructor this way. Instead of `std::vector<int> v = {begin, end}` you would usually write `std::vector<int> v(begin, end)`. But for some reason C++11 decided to make those two things mostly equivalent.

Re:How the STL Uses Explicit by gpderetta on Thursday June 27, 2024 @04:50AM (#40808614)
List initialization is quite nice, but the interaction with brace initialization introduced at the same time is a giant foot-gun.
Re:How the STL Uses Explicit by BobbyJo on Thursday June 27, 2024 @07:48AM (#40809462)
> But for some reason C++XX decided to....

Why I gave up C++.

That and because somehow package management is still a nightmare.

Re:How the STL Uses Explicit by UncleMeat on Thursday June 27, 2024 @10:34AM (#40810972)
This sort of UB detection requires bespoke work.

The compiler probably can figure out that the begin and end iterators here are referencing different objects but if you add just a bit more complexity to the code then the compiler won't be able to prove that.

Re:How the STL Uses Explicit by mwkaufma on Thursday June 27, 2024 @01:03PM (#40812634)
That's consistent with STL's move to use "explicit" and other narrowing annotations, as described in the article.
Re:How the STL Uses Explicit by ramon156 on Thursday June 27, 2024 @01:17AM (#40807491)
Id argue that c++ is not type safe. Yes, strings could be converted to ints in theory, but these types are obviously not the same, why not make it more explicit?
Re:How the STL Uses Explicit by maleldil on Thursday June 27, 2024 @05:05AM (#40808708)
Type safety isn't binary but a spectrum. It's obvious that C++ is more type-safe than JS but less than Rust, which is less than Haskell.
Re:How the STL Uses Explicit by eru on Thursday June 27, 2024 @05:25AM (#40808780)
Well, at some points it becomes even more complicated than just a spectrum.

Your types in different languages just track different things.

Eg Haskell's types (normally) don't track lifetimes nor ownership, but Rust does that. In contrast, Haskell likes to track whether side-effects like IO can occur at all, while Rust is happy to just let you eg open a file almost anywhere.

Re:How the STL Uses Explicit by chuckadams on Thursday June 27, 2024 @10:04AM (#40810680)
Haskell has linear types now, so there's your lifetime and ownership, though thankfully they're optional... wrangling linear types makes Rust look friendly and lenient.
Re:How the STL Uses Explicit by eru on Monday July 01, 2024 @01:55AM (#40842935)
Nice! I've only used linear types in Clean ages ago, but haven't checked them out in Haskell, yet.
Re:How the STL Uses Explicit by JonChesterfield on Thursday June 27, 2024 @05:52AM (#40808878)
C++ is obviously hilariously less type safe than JavaScript.

JavaScript will convert values from one type to a other at runtime but it's always absolutely sure what the type of the value is.

C++ will compile code that looks reasonable, decide it's UB, not tell you about that and proceed to do abject nonsense at runtime.

Considering C++ the more "type safe" one of the two is so far from accurate that I wonder if you've mistyped the name of one of the languages.

Re:How the STL Uses Explicit by eru on Thursday June 27, 2024 @10:58PM (#40817310)
I have a lot of sympathy for your point of view. Though have a look at Rust: it's generally considered much more typesafe than both JavaScript and C++, but it also has (some) dark corners of undefined behaviour with approximately all the same baggage as C++.

See also https://news.ycombinator.com/item?id=8206562 for a different point of view: dynamically typed languages are equivalent to statically typed languages with just a single static type.

Re:How the STL Uses Explicit by mofeien on Thursday June 27, 2024 @05:26AM (#40808788)
I agree. C++ is statically typed, as in everything has a type known at compile time. But it is also weakly typed, as in types can be be converted into others implicitly which only makes sense a fraction of the time and readily introduces accidental UB at other times.
Re:How the STL Uses Explicit by jandrewrogers on Thursday June 27, 2024 @10:50AM (#40811132)
You can make it both stricter and more explicit. This is a 30 year old API from when C++ was a very different language. In a modern context, this example was explicitly designed to be as loosely checked as it is, it isn't intrinsic.

Backward compatibility means they can't change this API to not allow these cases even if it is straightforward to do so.

Re:How the STL Uses Explicit by ycombinatrix on Thursday June 27, 2024 @02:41PM (#40813631)
>my C++ has gotten a bit rusty

i see what you did there