News for hackers. Stuff that matters.
Re:Coroutines are now in Clang trunk, libc++ by oblio on Friday May 26, 2017 @04:17AM (#14422678)
As a non-C++ coder there are two things that "scare" me about C++ (ok, maybe not scare, but are definitely big turn offs):

- lack of a proper, cross platform, package manager: I know the history, I know that C/C++ are basically embedded in the system and they use the system package manager, but in this age it just doesn't fell right... I've been spoiled by many years of using Maven and other similar tools

- template meta-programming plus the C++ legacy features which are probably lurking in many third-party libraries (simpler languages have fewer features to abuse and even when for whatever reason you have to use a relatively subpart third-party library, you know they can't do that much damage)

There's also the compilation speed, but as far as I know there are workarounds for that.

These things are, if not unsolvable in C++, at least many years away from being available.

Maybe an experienced C++ coder can destroy my preconceptions :)

Re:Coroutines are now in Clang trunk, libc++ by humanrebar on Friday May 26, 2017 @07:16AM (#14423247)
> Maybe an experienced C++ coder can destroy my preconceptions :)

- Generally C++ uses the OS-level package manager, like rpm or dpkg. It's not cross-platform and it doesn't have a nice interface in the source code (#include is... unfortunate), but there is a nice solution here if your organization has the discipline and tooling expertise to make it work.

- Template metaprogramming isn't bad to use at all. Everyone uses it every time they construct a vector<>. It takes a lot of skill to write, though, and unfortunately even users of TMP can end up with nasty and bloated compiler errors. Hopefully this will be addressed by "concepts" in forthcoming versions of C++, but it might be a while before that filters down to stable C++ compilers and libraries.

- The real issue that should scare you is something called "undefined behavior". It's very easy to do subtle things that cause you programs to break in weird and hard to debug ways. Nasty side effects that could theoretically include any side effect. Like saving garbage to your production database. By doing something as innocuous as overrunning an array.

https://kukuruku.co/post/undefined-behavior-and-fermats-last...

https://stackoverflow.com/questions/367633/what-are-all-the-...

There are tricks and tools to avoid undefined behavior, but I find that most C++ engineering orgs don't prioritize the tooling (linters, UB sanitizers, etc.) needed to let engineers do this productively. Consequently, a lot of writing good C++ involves detailed coding standards and/or very detail-oriented gurus poring over code reviews.

Re:Coroutines are now in Clang trunk, libc++ by missblit on Friday May 26, 2017 @11:39AM (#14424809)
And array over-runs are just the beginning! (friends don't let friends use idices over iterators)

Had a fun bug at work once where we somehow accidentally built against two subtly incompatible versions of the same library.

This actually mostly worked until some random virtual function call sometimes called the wrong function silently...

Re:Coroutines are now in Clang trunk, libc++ by petters on Friday May 26, 2017 @04:27PM (#14426888)
Yes, C++ without a monorepo is very difficult.
Re:Coroutines are now in Clang trunk, libc++ by taneq on Friday May 26, 2017 @07:48AM (#14423380)
Yeah, undefined behaviour was my thought too. There's a few warts with templates etc. but undefined behaviour is the granddaddy of all skeletons on the linguistic closet.

Realistically, C++ isn't actually a well-defined language unless you specify platform and language. You don't program in C++. You program in a C++-derived language jointly defined by the compiler and the hardware.

Re:Coroutines are now in Clang trunk, libc++ by marcosdumay on Friday May 26, 2017 @10:37AM (#14424333)
Besides the confusing error messages, C++ templates also tend to be weakly typed.
Re:Coroutines are now in Clang trunk, libc++ by HankB99 on Friday May 26, 2017 @09:17AM (#14423767)
I'm a former C++ programmer (I haven't had an assignment that used C++ for years, though I pressed for a limited subset on a recent embedded system) I likely never reached the sophistication of most of the respondents here and my concerns may have been addressed.

The things that concerned me about C++ were the pitfalls that could happen due to ignorance or omission vs. errors introduced by commission. For example forgetting to implement a copy constructor for a class that allocates member data. (That results in two objects that hold pointers to the allocated data following a copy operation and if one is deleted, the other points to now deleted data.) Perhaps there are better compiler warnings or static analysis tools that will reveal problems like that today.

My other concern is how big the language has grown. I recall my excitement when I first worked with C++ since it provided direct support for a lot of things I was doing with C (Object orientation, function pointers in structs and similar) with the addition of better type safety. Nowadays many of the language features are incomprehensible and beyond my skill level. I suppose largely because I don't work with C++ on a day to day basis.

Re:Coroutines are now in Clang trunk, libc++ by gpderetta on Friday May 26, 2017 @10:39AM (#14424348)
If you use a proper smart pointer time to store an owned object as recommended, you'll get sensible behavior: either the copy will be shallow (with shared_ptr) or the implicit copy constructor instantiation will fail to compile (with unique_ptr).
Re:Coroutines are now in Clang trunk, libc++ by fiddlerwoaroof on Friday May 26, 2017 @10:18AM (#14424210)
Doesn't std::shared_pointer help with the copy constructor issue?
Re:Coroutines are now in Clang trunk, libc++ by int_19h on Friday May 26, 2017 @01:55PM (#14425947)
If you mean using shared_ptr everywhere, then 1) this would be extremely non-idiomatic C++, 2) you can still forget to do so, and 3) the moment you do, the language makes it ridiculously easy to implicitly copy something.
Re:Coroutines are now in Clang trunk, libc++ by a13xb on Friday May 26, 2017 @09:33AM (#14423869)
I am a former C++ programmer who has moved on to the other languages/technologies and no longer suffer from Stockholm Syndrome.

This is just the tip of the iceberg. There are many dark corners, historic baggage, and complex interplay of language features in C++. This complexity breeds bad codebases plagued by subtle bugs created by misunderstanding of finer points of the language.

If these things scare you, run away in the other direction as fast as possible.

Re:Coroutines are now in Clang trunk, libc++ by xaa on Friday May 26, 2017 @11:29AM (#14424735)
I, on the other hand, am a primarily Python programmer being slowly lured to the Dark Side.

The thing I love about using C++ is that you get direct access to all these rock-solid libraries in C that everything is built on -- zlib, libcurl, etc. So instead of dealing with a tower of wrappers in a high-level language, each of which has quirks and bugs, you get that core lib, where you can safely assume 99% of the time any problem is your own fault. Even when a C++ wrapper exists, I use the C API just to reduce deps and avoid the kind of problems you're talking about, which I think boil down to templates most of the time. I don't use templates unless there is no other way.

This strategy works pretty well for me, but my codebase isn't huge and I'm not doing anything super complex -- just trying to speed up things that are too slow in Python, be it parsing or data structures. I think in practice it is best to use multiple technologies if possible in a project, each one suited to the task.

And WRT the coroutines in OP, I don't know the details, but the thing I miss most from Python in C++ is yield and generators, which hopefully coroutines will eventually help with. Defining your own iterators is very annoying.

Re:Coroutines are now in Clang trunk, libc++ by mpweiher on Friday May 26, 2017 @02:09PM (#14426032)
> you get direct access to all these rock-solid libraries

> in C that everything is built on -- zlib, libcurl, etc.

> So instead of dealing with a tower of wrappers in a

> high-level language

That's what I love about Objective-C: you get that, the direct access, and at the same time transparent, non-wrappered access to a high-level, dynamic object-oriented language.

Re:Coroutines are now in Clang trunk, libc++ by autoreleasepool on Friday May 26, 2017 @08:04PM (#14428079)
Don't forget about Objective-C++! That's where the true powers of the dark side are.

Side Note: Objective-C is such a criminally underrated language. I often see people complaining about the syntax, but it's just syntax. Once you get over it, I find that the language makes the OOP paradigm a joy to work with.

Re:Coroutines are now in Clang trunk, libc++ by xaa on Saturday May 27, 2017 @06:38AM (#14429618)
Honestly, I never seriously considered it. I thought it was more-or-less an "Apple thing". OFC it is supported on other platforms, but seemingly not widely used (I write scientific code that really only has to work on Linux).

But after looking at its feature set, I wonder how easy it is to get by without templates? It seemingly uses weak typing instead like Go for scenarios that would normally require generics/templates. My attitude towards templates/generics is that they are absolutely necessary for a good standard library and core containers, but implementation of new templates in your own code should be rare.

Also, I do like namespaces in general, although not necessarily C++'s implementation of them.

Re:Coroutines are now in Clang trunk, libc++ by a13xb on Saturday May 27, 2017 @08:45AM (#14429865)
I'll be a contrarian here and say that Objective-C is an ugly mess, and not even "because brackets". It's the language full of terrible hacks, historic baggage, and bolted-on features. Objective-C++ is basically the worst of both worlds. :)

Programming languages have advanced a fair bit since the 80s, it's time for Objective-C to die peacefully.

Re:Coroutines are now in Clang trunk, libc++ by actuallyalys on Friday May 26, 2017 @04:44PM (#14427022)
Have you ever tried Cython? It's always seemed cool to me, so I've always planned on using that if I ran into a case where I needed (relatively) direct C library access or wanted to speed things up beyond what straight Python is capable of.
Re:Coroutines are now in Clang trunk, libc++ by xaa on Friday May 26, 2017 @04:56PM (#14427110)
Sure. I use it for some things and straight C++ for others. Cython is good for simple things, like small tight loops.

One thing that is much more reliable in pure C++ is any kind of threading or OpenMP etc. Theoretically Cython has it, in practice it can cause very weird problems. Also if you want to use C (or C++) libs in Cython, you have to manually declare all the function prototypes before using them.

Also Cython has a tendency to make minor breaking changes to syntax every version, breaking my code and/or making it version-dependent. Since I distribute to others, the best method for linking performance intensive-code to Python I have found is:

1. Write the core in C++

2. extern "C" a simple C API for it

3. Compile both to a SO

4. Access the SO from ctypes

It is more robust than Cython IME. Another advantage of this approach is that you have now have a generic C library you can use anywhere else if you want, not just Python. And you don't have to link -lpython so the C lib can be used in places where Python isn't installed. Finally, it can be nice to have some C++ binaries for startup time, and AFAIK you can't compile binaries with setuptools.

Re:Coroutines are now in Clang trunk, libc++ by actuallyalys on Friday May 26, 2017 @05:56PM (#14427498)
Thank you for your very informative answer!
Re:Coroutines are now in Clang trunk, libc++ by aldanor on Saturday May 27, 2017 @05:44AM (#14429523)
If you're into both C++ and Python, I recommend pybind11 [1] - Cython is a crutch and moreover C++ is not a first class citizen in it. For reasonably large codebases Cython just doesn't scale and debugging is a total nightmare.

Disclaimer: I'm a contributor to pybind11.

[1] https://github.com/pybind/pybind11

Re:Coroutines are now in Clang trunk, libc++ by a13xb on Saturday May 27, 2017 @08:37AM (#14429845)
Please note that I specifically singled out C++ here, not C. C is not C++ (not even technically a subset of C++). It is a very different and a much smaller language.
Re:Coroutines are now in Clang trunk, libc++ by xaa on Saturday May 27, 2017 @01:20PM (#14430937)
Yes, I know they are different, but I was talking about C++. I heavily use the STL and greatly prefer it to C idioms. I also like namespaces. Templates can be very hairy but void pointers are not great either.

In short, I simply think C++ can be used responsibly if you limit yourself to the subset of features that you (or your team) can understand.

For example, there are people who go crazy with Python metaclasses and such. A statement about interacting language features being dangerous could apply to anyone in any language who is trying to be unnecessarily clever.

Re:Coroutines are now in Clang trunk, libc++ by pstuart on Friday May 26, 2017 @05:56PM (#14427501)
C'mon over to the Go side instead ;-)
Re:Coroutines are now in Clang trunk, libc++ by hellofunk on Friday May 26, 2017 @06:24AM (#14423056)
Template meta programming is unnecessary to use C++, even in its most complex of applications. It's nice if you can do it, but a lot of companies don't like developers to use TMP too much because it's not expected everyone will know or understand it. I consider it an extension to the language that is cool but not necessary for most of the work you do. It's great that it is there, and great that your compiler and library authors use it to make the tools you use very fast, but for your own code, it's just not a gripe you need to worry about.
Re:Coroutines are now in Clang trunk, libc++ by jackcviers3 on Friday May 26, 2017 @10:14AM (#14424180)
I see this sentiment all the time, in every programming language - x feature is for library authors, but it is bad for application devs because we cannot understand it. It's a terrible notion.

Royal you and we below, not specifically hellofunk or op.

You use the libraries, so your application uses the feature already. You should understand one layer of code beneath yours. You should have an interface layer between your code and the library. By not doing either ( because libraries use magical features ) you are coding yourself into a corner with a feature you don't understand.

The libraries use it so that their code can be more general and well-specified. The libraries are used by thousnands more developers than your code. Your code probably could also be easier to maintain if it was more general and well-specified. Imagine if thousands of people could reuse your authentication interface at your company! Think of the money you will save.

All it takes is time to learn a feature you must partially understand because you are using the library built ON that feature.

EITHER learn the feature, or use libraries that only use features you understand. If you can't use the language without the feature, you can't use the language without understanding the feature. If you allow libraries that use the feature in your app code, you should allow app code that uses the same feature.

Re:Coroutines are now in Clang trunk, libc++ by hellofunk on Friday May 26, 2017 @02:35PM (#14426192)
I don't quite understand this, sorry. Say I'm using a very high-level concurrency library, for lack of a better example of the top of my head. Now this library uses lots of kung-fu to spread tasks around to threads without me having to properly understand the complex techniques of thread pools and a myriad other things. After all, the library exists to make my life easier.

Are you saying I should not use such a library unless I understand all the techniques it uses? I doubt a significant portion of developers fall into that category of library users.

Re:Coroutines are now in Clang trunk, libc++ by jackcviers3 on Friday May 26, 2017 @07:31PM (#14427950)
Yes. If you don't understand one layer below the code you wrote (a rung below on the ladder of abstraction) then you cannot understand if you are even using the correct abstraction (if the library is doing the thing it says it does when you call x). You literally have no idea what your code does, or even should do.

A linked list is a perfect example. If you use a linked list, you should know the basic properties of a linked list. When given one from an unfamiliar library, you should go read its code. You should run some basic performance tests on it. You should separate it from your code via some basic delegating api, so that you can replace it with another implementation in the future.

And concurrency is another example - do you need, and does, your chosen library give you parallel execution, or merely asynchronous execution.

This isn't as onerous as it sounds -- you do it all the time. But blindly trusting any software without a proof of its correctness (encryption is an example of where you might not understand ecen the interface layet of the software, but use it directly anyway) is a dangerous habit.

If there's magic there that you don't understand and you choose the library, when that magic fails to satisfy some goal you need to understand why so that you can fix it, implement your own workaround, or swap it out with a library that does what you want.

If you use a concurrency library, and don't understand threadpools, block in a thread and threadlock your application, you are in trouble.

If you use IEnumerable, and don't filter out the results before you toList, you are in trouble.

If you use monads and think flatmap is stack safe, always, you are in trouble.

Note you don't need to know ALL the tricks. Just the ones employed by the functions you call.

Re:Coroutines are now in Clang trunk, libc++ by hellofunk on Saturday May 27, 2017 @12:06AM (#14428876)
I don't think you are making the point you think you are making, or you being unclear. Take the concurrency example. The is a big difference in understanding the high-level concept of parallelism vs serial execution, which you suggest any library user understand, vs. understanding the C++ techniques and raw code that interacts with low-level threads to provide the library functionality. A good library does not require its users to understand its implementation in order to use its API -- that would be ridiculous most of the time. The burden falls on library authors to provide a good API abstraction that does not require users to understand the implementation; though some bad APIs may in fact require this of the users due to poor design.
Re:Coroutines are now in Clang trunk, libc++ by jackcviers3 on Saturday May 27, 2017 @10:45AM (#14430260)
Yes, I think that I'm being unclear.

As a user, I need to understand the top level abstraction of the library I am using - the api. I need to read that api's code and understand what it does, (not any deeper) in order to use it.

If it is a low-level api that directly implements a thread-pool, I need to understand that. If it is a high-level template that implements the async continuation monad[1], I need to understand the api surface that I call, and just the body of that surface and type signature.

1: https://www.fpcomplete.com/blog/2012/06/asynchronous-api-in-...

Re:Coroutines are now in Clang trunk, libc++ by petters on Friday May 26, 2017 @04:26PM (#14426877)
> lack of a proper, cross platform, package manager: I know the history, I know that C/C++ are basically embedded in the system and they use the system package manager,

I think the problem is deeper than that and that the problem could be that C++ does not have a standard ABI. It is compiler-specific. Therefore, having a system package manager does not work (as it does for C).

I compile my personal C++ codebase with four different compilers and different debug settings. The only way to manage that is to have a monorepo with all my dependencies checked in .

Re:Coroutines are now in Clang trunk, libc++ by Teknoman117 on Friday May 26, 2017 @03:46PM (#14426635)
I've been wondering if if a package manager is something that should be considered part of a language or just a distribution of that language - take npm for instance. It's not a "package manager for JavaScript." It's a package manager for node.js, which is a javascript runtime environment. Python's pip was added long after the inception of the language, there are plenty of package managers for PHP, etc.
Re:Coroutines are now in Clang trunk, libc++ by entelechy on Friday May 26, 2017 @06:20AM (#14423040)
there is the https://buckaroo.pm package manager.