Hacker News new | past | comments | ask | show | jobs | submit login
Looking at C++14 (meetingcpp.com)
51 points by jlemoine on March 15, 2014 | hide | past | favorite | 58 comments



>C++14 brings core language support for binary literals, which means you now can integrate binary literals as such in your code:

>char c = 0b01011010

I can't believe this took TWENTY YEARS (or at least that's how long I personally have been waiting). Hurray! (I'm going to hobble my walker over to the desktop and start codin' binary.)


Here's one of my all-time favorite way to write binary literals in C by abusing define:

    #define HEXIFY(X) 0x##X##LU

    #define B8IFY(Y) (((Y&0x0000000FLU)?1:0)  + \
                     ((Y&0x000000F0LU)?2:0)  + \
                     ((Y&0x00000F00LU)?4:0)  + \
                     ((Y&0x0000F000LU)?8:0)  + \
                     ((Y&0x000F0000LU)?16:0) + \
                     ((Y&0x00F00000LU)?32:0) + \
                     ((Y&0x0F000000LU)?64:0) + \
                     ((Y&0xF0000000LU)?128:0))

    #define B8(Z) ((unsigned char)B8IFY(HEXIFY(Z)))
And now you can write:

    B(01011010)
Etc.

If you like this, see my blog post about bithacks.h:

http://www.catonmat.net/blog/bit-hacks-header-file/


Using octal (0o) gives you larger representable numbers, fwiw.


Boost has a macro that's usable in plain C as well, since it uses only the preprocessor.

  #include <boost/utility/binary.hpp>
  char c = BOOST_BINARY(01011010);


Yeah but that is a but similar as BOOST_FOREACH before c++11 -- it just isn't making things any prettier. I think most people nowadays are conditioned to parse the enum-as-bitmasks 0x01, 0x02, 0x04, 0x08 etc, so i would be reluctant to use boost's version in that case. The new operator, however, seems pretty sweet for that use case!


There is no need for binary literals. Every low level programmer should know the first 16 hexadecimals in his sleep.

With that you can simply do char c = 0x5A. It is more readable since there are more distinguishing characters and is shorter. I actually made a mistake when I first scanned your numbers and had to look carefully. Imagine if the number was a 64bit integer.

Also <bitset>, if you intend to use c++ correctly.


You shouldn't use binary everywhere, just like you shouldn't just hex everywhere. Binary literals make sense for bit data. For example, coding an icon for a game:

    char unsigned bottomLeftCorner[8] =
    {
      0b11000000,
      0b11000000,
      0b11000000,
      0b11000000,
      0b11000000,
      0b11000000,
      0b11111111,
      0b11111111
    };
They may, at times, also make sense when coding some low-level protocol.


C++ is still missing optional Reflection/Introspection. With that feature it could easily replace majority of todays typed languages (with exception of language such has Haskell or Rust). Reason is that reflextion allows to close a 'external data types' dissonance that currently is present in C++. In other words it is not possible to develop 'framework software' that can introspect plugin/consumer code to derive how they view the externally defined data sources (eg Databases, UI kits, JSON streams/etc).


The first time I wondered how the hell C++ didn't support introspection, I was 1/3 as old as I am now. I have literally been wondering for most of my life.

But hey, at least they have a Turing-complete template language to go with their macros! Priorities, right?


Yes, priorities. The evolution of C++ is driven by its users in the industry. That C++ not yet has support for reflection or introspection is an indication that there hasn't yet been a great need for it.

Any C++ user (you know, the people who actually use the language) will tell you that templates is a central part of the language and something that is far more important than introspection.

Anyway, like I said in the other comment, there's a study group for reflection now. We'll see what comes out of it.


> Any C++ user (you know, the people who actually use the language)

Funny, because I am a heavy C++ user (why did you assume differently?). C++ probably accounts for between 1/3 and 1/2 of my lifetime lines-of-code. Trouble is, I've had to use it for more than algorithms work, which is the only place I've ever seen templates shine. I've used a half dozen C and C++ GUI frameworks that painstakingly work around the introspection issue, and while these frameworks often make do quite nicely without templates, they always have a bolted-on monstrosity of an introspection system. Qt is probably the most direct example: they built their own preprocessor/parser around C++ to take care of their need for introspection.

I'm glad there is a study group, but the absence of introspection has been hurting the C++ community for a long time. It's the flaw that has launched 1,000 high-level languages and 100,000 dirty hacks.


> But hey, at least they have a Turing-complete template language to go with their macros! Priorities, right?

And with that you can build reflection:

http://stackoverflow.com/a/11744832/375343


Great, now all I have to do is convince every company in the world that uses C++ to paste a macro into each class and keep duplicates of all their variable declarations.

(Poe's law applies, sorry if you were attempting humor and I missed it.)


C++ study group 7 (SG7) is looking at various reflection proposals.

https://groups.google.com/a/isocpp.org/forum/?fromgroups#!fo...


What is the current state of C++11 support in major compilers (e.g. G++, clang, MSVC)


It's excellent in GCC and clang. GCC 4.8.1 was feature complete.

GCC C++11 status: http://gcc.gnu.org/projects/cxx0x.html

Clang: http://clang.llvm.org/cxx_status.html

MSVC is not as good. I don't have any links handy, but anecdotally it still fails to compile some of my code that compiles fine in GCC.


GCC 4.8 (and even earlier) has <regex> but it doesn't actually work. I guess it will work in 4.9, but haven't gotten to try it. This glaring omission somehow didn't make the list you linked, which is otherwise exceedingly comprehensive.


Good point, I guess that table only shows language features.

Here's the library features table: http://gcc.gnu.org/onlinedocs/libstdc++/manual/status.html#s...

Not feature complete if you take that into account, I'm afraid.


Microsoft should join the LLVM group and just port any MSVC extension not supported in clang over already. :-)


http://cpprocks.com/c11-compiler-support-shootout-visual-stu...

A little out dated but a good starting point. I'm using gcc 4.6.1 and am loving the C++11 features, only thing I've noticed it missing is implicit capture of this in lambdas.


Full in g++ 4.8 and Clang 3.3 with the exception of <regex>. MSVC is still behind.


I was really excited about learning/using some of the new stuff coming in c++11 and so on until a new job introduced me to Go lang. Now it seems like all of that stuff and more, elegantly built in instead of bolted on. To be fair I think it has a big bent towards server apps and not all general purpose stuff so it only to me seems better for a subset of all c++ work. on the other hand, Mozilla's Rust also looks interesting. Does anyone else feel like c++ is finally starting to be replaced in different segments by more target newer more elegant languages?


I don't think Go is attracting many programmers away from C++ (in fact Rob Pike has expressed surprise at this) because it lacks some of the important good qualities of C++: strong typing (which Go lacks because of its lack of templates/generics) and RAII-style resource management. Instead Go is attracting programmers away from interpreted languages like Python since it has many of the nice qualities of interpreted languages while being very fast.

Rust may be a different story (still too soon to tell) because it shares many of the fundamental philosophies of modern C++ without having a "bolted-on" feel. Still, it will be very hard to ever displace C++, because so much code is currently written in C++ and C++ has proven to be a very good language for code that needs to last decades.


> Still, it will be very hard to ever displace C++, because so much code is currently written in C++ and C++ has proven to be a very good language for code that needs to last decades.

I'm pretty sure that Rust devs are aware of that which is why they made Rust compatible with C/C++.


The big issue is that C++ FFIs are notoriously hard to implement. Often C wrappers are the only way to go (Rust has an excellent C FFI). As far as I know, I think D is one of the best out there regarding C++ compatibility, but it is still lacking.


>Go lacks because of its lack of templates/generics

This is one of my big frustrations with Go. I see lots of ugly `interface` based patterns.

I wish more languages would adopt Haskell's typing system (at least partially). It is truly beautiful.


This—also, C++11 is an amazing improvement over C++03, and C++14 looks like another step in the right direction.

For a small example, a friend talked me into implementing a few Scala collection operations in C++11. Here's the result: https://gist.github.com/LnxPrgr3/6547131

Usage looks like this:

    const collection<vector<string>> names = {"Daniel", "Chris", "Joseph"};
    return names.reduce_left<string>([](const string &total, const string &value) {
        return total + ", " + value;
    }) == "Daniel, Chris, Joseph";
    // ...
    const collection<vector<string>> strs = {"1", "2", "3", "4", "5"};
    auto rv = strs.map<collection<vector<int>>>([](const string &x) {
        return atoi(x.c_str());
    });
    return rv.size() == 5 && rv[0] == 1 && rv[1] == 2 && rv[2] == 3 && rv[3] == 4 && rv[4] == 5;
This is from a collection of tests, which looks like this:

    struct test {
        const char *name;
        function<bool ()> fn;
    };
    
    const vector<test> tests = {
        {"Foldleft", []{ /* .... */}},
        {"reduceLeft on empty throws", []{ /* ... */ }},
        // ...
    };
    
    for(auto &test: tests) {
        cout << test.name << ": " << flush << (test.fn() ? "PASS" : "FAIL") << endl;
    }
    
I would've never considered something like this useful in C++03—callers would have to create named functor classes just to do some trivial one-line operation, this vector of tests would've had to have been a series of push_back calls, and iterating over it would've been quite a bit uglier.

This isn't at all an exhaustive list, but these are the biggest things that come to mind when I think of what C++11 gains over C++03.


If anything, C++11/14 take the steam out of the languages that were gaining ground against really painful C++03 coding.

In benchmarks Go keeps performing somewhere between Java and C++, but it isn't at the baremetal performance of C / C++ yet. Don't know if it can get there with its abstractions. Rust is closer, but it concedes a lot of glyphic syntax (such as requiring :: for scope like in C++ rather than, say, one colon) but I don't see it hitting prime time until Mozilla is ready for Servo to enter Firefox. It needs a big project behind it to show its capable.


Wait, I'm confused. I would think that the opposite would be true. You don't even have generics in Go. Rust is probably more what you're after.


I wish they add a new operator: "in" ... then it can be defined in maps and whatnot for lookups: if (123 in x)


You're not thinking C++ish.

There is a wide range of algorithms to find/modify/replace data in containers.

Let's say you have a set of ints, doing what you want is the following:

    std::set<int> blah;

    // ... some stuff happens ...

    if (blah.find(123) != blah.end())
    {
    // ...
    }
Now, you're saying, "but my container doesn't have find!". Not a problem, you can use std::find!

    std::vector<int> v;

    // ... some stuff happens ...

    if (std::find(v.begin(), v.end(), 123) != v.end())
    {
    // ...
    } 

Note that v can be ANYTHING, as long it supports forward iterators (which all containers do).

Now you're saying, "but it's not very efficient! The complexity of find is O(n)!"

True, true. If your container is sorted, you should use binary search O(log n):

   if (std::binary_search(v.begin(), v.end(), 123))
   {
   // ...
   }
What's great about this is that it works on any container, provided it's sorted.

Then, what you can do is write a metafunction that will call the member function find() when it exists or use std::find() when there's none. This will automatically, and at compile time, use the most efficient way to check for the existence of an entry.


I am not talking about how I end up searching the container. I am talking about the syntax. Besides, how a container is searched should be abstracted away in the container's implementation and the algorithm should be documented.

Compare this syntax:

> if (std::find(v.begin(), v.end(), 123) != v.end())

To

> if (123 in v)

If in is an operator and overloaded by std::vector, then it's easy to implement.


> If in is an operator and overloaded by std::vector, then it's easy to implement.

However, searching a `std::vector` is not really part of its implementation. So, requiring every single range to overload an operator for trivial searching is not good, especially since there are only a few containers that have non-trivial searching.

Instead, the range-based find could be specialized for containers that have non-trivial searching instead(perhaps it calls a `.find` method if available otherwise it does trivial searching).

In [Linq](http://pfultz2.github.io/Linq/), the find is specialized for mapped containers and for strings(it doesn't check for a `.find` method since that can't be done on msvc). So you can search a `std::vector` like this:

    std::vector<int> v = { ... };
    auto it = v | linq::find(123);
And you can also search the keys of a map like this:

    std::map<int, std::string> m = { ... };
    auto it = m | linq::find(123);
Plus, it has a contains function, so you can do this:

    if (v | linq::contains(123))
Or this:

    if (m | linq::contains(123))
There really is no need for a new operator just for this, since a function will suffice. However, if you really inclined to this, you could always write your own [named operator](https://github.com/klmr/named-operator)(although I don't know if it would become standard):

    if (123 <in> v)


You can say the same thing for the new range based for loop in C++11.


I hate to do this, but I think you totally misunderstood the point of the STL.

The fact that algorithms are separated from containers is a major feature of the STL and one of the major reasons why it is so awesome.

By having algorithms separated from containers you implement algorithms only once and only have to give your container the right properties to use (an) algorithm(s).

You reduce coupling and the chances for errors and bugs. When you need to switch to a different containers, you don't have to rewrite your code. You can also try different algorithms easily.

> if (123 in v)

I'm sorry but C++ is about describing precisely what you want to do and how you want it to be done to get the maximum performance out of your machine.

What is "in"? What does it do? How does it allocate memory? How can I get the position of the entry? Which algorithm is used to search for the entry? What must I do to support "in"?

On the other side,

> if (std::find(v.begin(), v.end(), 123) != v.end())

I use a O(n) algorithm to search from the beginning to the end of the container for an entry equal to 123.


> how a container is searched should be abstracted away in the container's implementation

lol, no, god no. I think you got the STL completely wrong.


I see. So a map implemented using an RB Tree is not abstracting away the implementation?


I do find it odd that there isn't even a .contains(x) function and I have to use .count(x)


C++ suffers from the too many cooks in the kitchen syndrome. They sometimes miss the basics.


> 3781 - Single quotation mark as digit separator

Hold on a minute. Why is this even a thing? Do people really use HUGE numeric literals and have so much trouble reading them that this is needed?

This just sounds like another parsing nightmare that really should belong in syntax highlighting rather than exist as some obscure language feature.


> Do people really use HUGE numeric literals

Yes. Engineering code uses numeric literals with many digits all the time.

> and have so much trouble reading them that this is needed?

Digit separators make digit omissions/additions much easier to spot. Imagine spending a day trying to track down a "everything explodes" bug, systematically eliminating numerical sources of error one by one, only to find that the problem is a misspecified boundary condition that you didn't catch the first time around because you were counting the number of zeros as opposed to the number of digits.

    c = 3000'000'000 /*  m/s  */
^ I can spot this out of the corner of my eye.

    c = 3000000000   /*  m/s  */
^ This? Not so much.


I prefer this alternative:

  c_millisecs = 50000 * 60 * 1000; // 50,000 minutes


That only works for unit conversions where they're defined as ratios of each other. Nature has physical constants and engineers have environmental and design parameters that can't be written that way unless you constantly change units, which is a bad idea in a language without built-in unit checking (most of them).


I prefer

(1000 * 60 * 60 * 24 * 2) == 2 days


For the love of God, or some other entity you find holy or unholy.

Stop using this bastard of a language. Its an offront to software engineering and must simply die


Do you play games? Do you play console games, or desktop games? Do these games support 3D rendering? Soft shadows? Physically based lights? Pathfinding of crowds of people or units? Literally hundreds of thousands of projectiles? Networked replication? Leverage all the cores of your desktop/device/console while doing the above? Support unique or specialized data structures? Execute a runtime that CAN'T tolerate non-deterministic GC pauses?

I make games. What am I supposed to code that in? Fucking javascript? Ruby? C#? Go stfu and die yourself. If you want to come up with a language that can get the job fucking done than by all means, go for it and fail miserably. Otherwise, stop using any of the products that leverage C++. We don't want you.


Hopefully Rust will take a chunk out of this market, but I agree that folks don't seem to realize how important systems programming is in supporting their higher level languages.


:(


Im sorry your too much of a pussy to just write C.


Good compile-time dispatch is a relatively easy in C++, but damn-near impossible in C. There are actual legitimate reasons to use C++.


I hear that not all development is web development. In fact, those in the know know that even very popular well-known companies that make their profits from web applications heavily leverage C, C++, and tools (and languages) that are themselves built with C and/or C++ or run in embedded or VM processes that are themselves built with C and/or C++.

I find it amusing that the new languages being heavily touted in the non-functional space (that would be Go, D and Rust) are all using C and C++ as their targets for replacement. Everybody loves to hate C and C++, yet the tech world literally runs on them, and will for the foreseeable future.

This isn't to say there isn't anything better, or that they'll never be replaced.

You also misspelled "affront."


What would you suggest instead? Until there is something that is as general purpose as C++ and has the same level of performance it will continue to survive.


Rust?


Maybe in 4 or 5 years, if things go well. There hasn't even been a 1.0 release yet. That's the bare minimum necessary for a lot of existing C++ users to even consider Rust as a potentially viable option.

Assuming Rust 1.0 is released sometime this year, it'll still take a number of years before Rust even begins to offer the very wide range of libraries/frameworks that are available to C++ developers.

Interfacing with these existing C++ libraries/frameworks may speed things up, but at that point its disputable whether it's really Rust being used.

Rust may be among the most promising alternatives, but it's just not there yet, and won't be for some time.


Not everyone works in webdev. Some people do embedded development, and use a reasonable subset of C++.


Get out of your bubble.


Care to justify your bile?


I here by announce, that C++ next version will be called D! More links here: http://dlang.org




Consider applying for YC's Spring batch! Applications are open till Feb 11.

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: