Live data from Hacker News

Help me sort out the meaning of “{}” as a constructor argument

scottmeyers.blogspot.com

171–180 of 181 posts

Re: Help me sort out the meaning of “{}” as a constructor argument

#171
post #69

Earlier quoted context omitted.

Sure, I use and like both of them. C++ for 3D graphics, Scala for Big Data. Yet I have seen so many things go wrong in both of them so my perspective is a bit different. Imagine if somebody redefines basic operators to mean something different, starts throwing int as exception in C++ or use templates with template parameters with number parameters and you have to figure out what exactly does this thing do? Or in Scal…

How is that different from using a C function called add_two_ints which deletes the root file system and returns 42? I don't think it is possible to create a language that can prevent dumb code from being written.

It's not about dumb code. Actually both C++ and Scala can allow you unbelievably clever code which is also super difficult to understand by somebody uninvolved. Remember how some Haskell guys were complaining they aren't able to understand the code they wrote at the top of their game anymore?

Re: Help me sort out the meaning of “{}” as a constructor argument

#172
post #137

Earlier quoted context omitted.

The parent was asking the goldilocks question -- was there ever a point where C++ was not too complex like modern C++, e.g. this {} issue, but had enough features (contrast with C, which doesn't have enough features for many applications). I don't think there was such a moment. Apparently move constructors were a de-optimization in the case of std::vector. As far as I remember, it's related to iterator invalidation a…

At what point is it mentioned in the video? AFAIK small optimization on std::vector was already invalid since .swap() needed to keep existing references/iterators valid, couldn't throw or call copy constructors/assignment. RVO being transparent would be nice, though. There's a proposal somewhere to make it guaranteed in some circumstances, but it's still fairly opaque when reading code

Sorry I don't recall offhand. It was definitely Chandler Carruth who mentioned this, and he has a handful of videos on YouTube from CppCon. They are all worth watching if you care about such things :)

I don't know the details but I'm fairly sure that the issue is that move constructors in C++11 made small size optimization impossible in some cases. I think he works on the LLVM optimizer so that would be a primary source and not hearsay.

Re: Help me sort out the meaning of “{}” as a constructor argument

#173
post #152

Earlier quoted context omitted.

Because in practice they lead to exceptions not being handled properly with a lot of boilerplate try catches. If you can't do anything sensible with an exception (like retry a couple of times) then they shouldn't be caught. The other alternative is chaining throws on function definitions up the call stack. Most new libraries don't use checked exceptions. They were a good idea in theory but not in practice.

What do you think of languages like Rust, Go, or Haskell which return errors as part of the return type? That's somewhat akin to having all exceptions be checked.

This is the exact opposite of checked exceptions, it returns an error you don have to handle at all.

It turns me off go and Haskell altogether because they are languages suitable to applications. I think it's going to lead to a lot of apps in the wild ignoring errors.

Rust is a bit different because it's a systems language, it makes sense there.

Re: Help me sort out the meaning of “{}” as a constructor argument

#174
post #44

Earlier quoted context omitted.

The main advantage of C was that it allowed you to type stuff super fast comparing with Pascal ( {} instead of Begin .. End etc.) and had some very handy shortcuts for often used operations like ()?:, ++, --, += etc. Less verbose language, less need to type syntactic structures. You could basically keep the flow of what is in your mind with the progress on your keyboard and forget about typing it; you were simply ass…

I'd say the two more important advantages were a) the bare-metal view C gave you, down to individual bytes, which was important for systems-level programming, and b) the lack of overhead from things like bounds checking and garbage collection, which was useful on the butt-slow machines in the 70s and 80s.

Turbo Pascal (from early versions) could very much handle individual bytes (and IIRC, had bit manipulation primitives like bitwise and/or/xor/not, shr, shl, etc.), and could even address memory at fixed locations, such as the video memory on the IBM PC (and segment:offset x86 memory at that). Don't know about other Pascal implementations, such as the others pjmlp has mentioned elsewhere in this thread, but would not be surprised if some of them could as well. I agree with pjmlp's statement (again, elsewhere in this thread), that C is probably being compared (to C's advantage) against early standard Pascal (which was a limited, academic language), not the commercial implementations which would have been / were more pragmatic. And I say this as a guy who liked and used both Turbo Pascal and C (C on DOS, Unix and Windows) a lot, for long, earlier, including being team lead for a successful Windows C database middleware product.

Re: Help me sort out the meaning of “{}” as a constructor argument

#175
post #173

Earlier quoted context omitted.

What do you think of languages like Rust, Go, or Haskell which return errors as part of the return type? That's somewhat akin to having all exceptions be checked.

This is the exact opposite of checked exceptions, it returns an error you don have to handle at all. It turns me off go and Haskell altogether because they are languages suitable to applications. I think it's going to lead to a lot of apps in the wild ignoring errors. Rust is a bit different because it's a systems language, it makes sense there.

I don't think it's the exact opposite at all. It forces you to "catch" the exception, but doesn't force you to do anything with it, the same as a checked exception.

Like in Go I can do:

    f, err := os.Open("foo.bar")
    
I am then free to ignore err or do something with it, but the type system forces me to at least acknowledge that it exists. It's the "compiler forces you to acknowledge the possibility of an error" that makes them pretty similar to checked exceptions in my opinion.

Re: Help me sort out the meaning of “{}” as a constructor argument

#176
post #173

Earlier quoted context omitted.

This is the exact opposite of checked exceptions, it returns an error you don have to handle at all. It turns me off go and Haskell altogether because they are languages suitable to applications. I think it's going to lead to a lot of apps in the wild ignoring errors. Rust is a bit different because it's a systems language, it makes sense there.

I don't think it's the exact opposite at all. It forces you to "catch" the exception, but doesn't force you to do anything with it, the same as a checked exception. Like in Go I can do: f, err := os.Open("foo.bar") I am then free to ignore err or do something with it, but the type system forces me to at least acknowledge that it exists. It's the "compiler forces you to acknowledge the possibility of an error" that ma…

Yeah it's similar in that sense, but checked exceptions force you to acknowledge every type of exception that can be thrown, or one generic one. If you can't handle it then they force you to list every type of exception that can be thrown all they way up the chain.

Re: Help me sort out the meaning of “{}” as a constructor argument

#177

Earlier quoted context omitted.

Well, the issue is not brace initialization per se, but the ambiguity with initilalizer_list.

Yes, either feature in isolation would have been an improvement to C++, but their combination was a mess. Probably one of the features shouldn't have been added, or their combination needed some serious tidying.

Was there a reason that array style braces ([]) weren't used?

Re: Help me sort out the meaning of “{}” as a constructor argument

#178
post #171

Earlier quoted context omitted.

How is that different from using a C function called add_two_ints which deletes the root file system and returns 42? I don't think it is possible to create a language that can prevent dumb code from being written.

It's not about dumb code. Actually both C++ and Scala can allow you unbelievably clever code which is also super difficult to understand by somebody uninvolved. Remember how some Haskell guys were complaining they aren't able to understand the code they wrote at the top of their game anymore?

Being too clever or too terse is possible in any language though. It is an education and experience problem, not a language problem.

Some languages may be slightly worse than others, but the root cause (and solution) is the same across the board.

Re: Help me sort out the meaning of “{}” as a constructor argument

#179
post #31
post #8

Earlier quoted context omitted.

C++ is hard. If one sticks to a strict subset it is a nice language. The problem is the code one didn't write. Even the STL is ugly to use. They are trying to fix the language by adding features but it's like Javascript, the old ugly ones are still part of the spec.

The problem is that even if all team members across the company agree on the subset, it might change its meaning depending on which language version (ANSI) and compiler vendor/version is being used.

Yes you are absolutely right. C++ compiler ecosystem is far from being monolithic.

Re: Help me sort out the meaning of “{}” as a constructor argument

#180
post #37
post #9

Earlier quoted context omitted.

C works great, as an alternate to assembler, to bootstrap unix up on meager, 80s style, hardware. Based on things like the shell tools and languages like awk (and other related descendants), I don't think even the unix creators meant for much application level work to be done in C, though, but by assembling components in higher level languages. Try telling that to The Management and all the macho/masochistic Real Pro…

Worse is that even the C creators saw the danger of using C without computer assisted validation and created lint in 1979. https://www.bell-labs.com/usr/dmr/www/chist.html Yet to this day, many still don't use any sort of static analysis tool.

To be honest, I seldom used lint, either, when I was starting out (although I suppose I cheated by using the Borland IDE in the early 90s). However, when using gcc in the mid to late 90s, it was just too easy to tack on -Wall (enable all warnings) to the options. No real excuse not to always check things, at that point.
Post reply on HN