1. 10
  1.  

  2. 5

    I’d highly recommend Mike Acton’s CppCon 2014 talk (1h30m) explaining how data oriented design is done in C++ (in the games industry no less) since the author stated that C++ is not well suited for it. The result is obviously very different from object oriented or highly generic C++, and it’s funny how some members of the audience at the end were a bit appalled at the “bad design” :) but I don’t think this makes C++ a bad choice (or a worse choice than C) for it.

    It’s also an outstanding video for anyone wanting to get into games, regardless of language. The designs used here translate very well to both the C and C++ languages.

    1. 4

      C++ because you can write it in a C or C++ way, you can even mix and match different parts, ie. std::string in your logging code but only raw functions exposed to the application. Basically C++ doesn’t you to either but C only does.

      1. 8

        Mixing and matching C and C++ is somewhat of an antipattern.

        1. 2

          No it’s not! mixing free and malloc is, but C++ is a superset of C.

          C++ is designed to mix with C!!

          1. 3

            Ebola is designed to mix with people, my friend, but it is seldom for the benefit of the latter. :(

            More usefully, mixing C with C++ tends to mean that you get all of the maintainability of long-form C code combined with the readability and compile times of C++ code.

            If you need a higher-level language than C, just embed an interpreter or make a bindings for your C library.

            1. 1

              C++ has some of the most powerful abstraction facilities with the highest performance possible. Often your C++ code will be simpler AND faster than C. Simplicity is often achieved by using more complex constructs underneath.

              Embedding an interpreter only makes sense if you want dynamic code compilation. Embedding an interpreter will NOT give you higher level abstractions by just binding your C library. You will also need to write higher level constructs in that guest language. If you don’t need the dynamic features, might as well write using C++’s abstraction mechanisms.

              For example, here is a simple thread safe queue implementation supporting both blocking and non blocking pop that I wrote.

              I would love to see the equivalent C implementation that has both the type safety and simplicity of use.

              1. 1

                For the C version, you’d need to have a standard library with decent threading primitives first. :)

                Also, if type safety was important, you’d be better off using a language (Haskell, OCaml, etc.) that actually does something useful with the types.

                I’ve gotta get dinner, but there are a lot of reasons to use another language than C and save it for the performant parts.

                ~

                For the simplicity/ease-of-use argument, I’d point to another language. How would you do this in C++?

                ["a","b","c"].map( function sayHi(greetee){
                    console.log("Hi, " + greetee + "!\n");
                } );
                

                (And no, std::transform is not this simple.)

                1. 1

                  What is this, code golf for ants!?

                  C++ equivalent to the above is

                  for(auto greetee : {"a", "b", "c"}) 
                      cout << "Hi, " << greetee  << "!\n";
                  

                  Obviously didn’t use a function called ‘map’, though transform in c++ IS map. We can write map as a wrapper to transform that takes containers.

                  Though not sure what you are mapping to there since you just write out to console. sayHi in your case is not a function but a subroutine, which makes my for loop the appropriate construct.

                  1. 2

                    Hah, love the “for ants” reference! :)

                    So, the sayHi is a function–earlier versions of this had it as a separate function, and at one point even as a function returning a function, just to demonstrate the ease of closures and whatnot in Javascript (really, here, just !C++).

                    Same thing could’ve been written as a for loop (with alarmingly similar syntax to yours, frankly), but that would’ve skipped over the interesting bit about semifunctional programming.

                    1. 1

                      Ok, using closures in C++ would look like

                      auto greets = {"a", "b", "c"};
                      for_each(begin(greets), end(greets), 
                          [](auto g) { 
                              cout << "Hi, "  << g  << "!\n";
                          });
                      

                      As you see, closures in c++ are easy and terse.

                      1. 1

                        Are begin and end some new standard lib functions/macros to get the iterators for a compatible collection type?

                        1. 1

                          They are shorthand for greets.begin() and greets.end(). However, the begin and end functions also handle arrays so it is more generic to use the functions.

          2. 1

            I just hide the C++ behind macros.

        2. 3

          Very similar to handmade hero school of thought. Really enjoyed this read.

          1. 1

            If only my pet project was further along, I feel like it might be a good fit for what this guy wants.