Announcement

Collapse
No announcement yet.

GCC Developers Look At Transitioning Their Codebase To C++11

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • #31
    Originally posted by Vistaus View Post
    With so many people disliking using the latest and greatest (in this case C++20) for coding, instead using older versions for a while longer, I wonder if anybody even uses the latest and greatest?
    C++20 isn't the latest and greatest. It is still future tech, since the none of big features are yet implemented in a non-experimental way by any compiler. C++17 sees some uses here and there, especially in high-frequency trading and other industries that are fast moving on specific platforms and doesn't need to ship stuff to customers on many platforms. But we are seeing a slow transition from C++14 to C++17 in industry standard C++ after MSVC finished support for it last year. Unfortunately C++17 is still not industry ready on the standard library front as MSVC and GCC only finished library support last year, and clang is still far from being finished with implementing C++17 in libc++, and when it is finished it will likely be a few years after that before Apple picks the implementation up for their proprietary versions of clang on macOS and iOS.

    Comment


    • #32
      Originally posted by kpedersen View Post
      This didn't compile on my RHEL 6 compiler (-std only goes up to 11). This is still our main server target unfortunately.
      Install devtoolset-8, and get the officially supported GCC 8 and libstdc++ which is completely compatible with the base CentOS 6 system.

      Comment


      • #33
        Originally posted by nanonyme View Post
        Do also considering the bootstrappability requirement. You need an older GCC to build a newer GCC and unless you can have quite large version difference between the two, it will be quite painful for LTS distros.
        C++ would be totally wrong way if they really cared about bootstrapping. It's a horribly complex language and the main productivity enhancements (strong typing, modules, functional features etc.) are available in other, simple languages.

        Comment


        • #34
          Originally posted by AsuMagic View Post
          Manual memory allocations are essentially always a terrible idea.
          Most of the time you can do the job with unique_ptr and it will neatly manage the lifetime of the held object.
          Okay, so you mean manual deallocations. You can still use-after-free, with std::unique_ptr<>, but it's certainly a lot less likely.

          We're not yet at the point of a true garbage-collected language, but I don't want that. If I want true garbage collection, I'll use something other than C++.

          Originally posted by AsuMagic View Post
          Even on the simplest stuff C++03 is annoying: No initializer lists, the stupid > > syntax rule, being unable to call a parent constructor or inherit from them...
          Well... C++03 has initializer lists - just not if your struct/class has a constructor.

          Regarding the requirement of a space between template parameter brackets (i.e. "> >"), that's just silly. After the first time tripping over it, you just learn to put an extra pair of spaces inside your <>'s. Problem solved. It's not ideal, but I don't think it rises to the level of the rest of the items in your list.

          I don't get your point about parent constructors - of course you can call constructors of your baseclasses! What C++11 adds is the ability for derived classes to forward baseclass constructors, or for constructors to explicitly call sibling constructors of the same type.

          Originally posted by AsuMagic View Post
          auto is not only useful for "laziness". It is very convenient for metaprogramming, and allows avoiding needless verbosity or workarounds.
          This.

          Originally posted by AsuMagic View Post
          Seriously, if you still are willingly using C-style arrays in 2019, I just don't ever want to have to deal with your code. I never ever found any reason not to use that other than pure masochism.
          If I'm using an initializer list, then std::array<> forces me to redundantly specify the length as a template parameter.
          Code:
              int vals[] = { 1, 2, 3 };
          This automatically dimensions the array as int[3]. Sure, one could do that with a std::vector<>, but that triggers heap allocation, which one might not want.
          Last edited by coder; 30 September 2019, 10:20 PM.

          Comment


          • #35
            Originally posted by tildearrow View Post
            Also, is it possible to access the associated iterator using the for (type i: var) {} syntax? Will come in handy when having to erase stuff in arrays.
            Err... you mean erase from vectors? You can overwrite array elements, but you can't erase them.

            Anyway, if you might need to erase, I think your best options are:
            • use iterators
            • iterate by index (if randomly-accessible container)

            If an associative container, you can also erase by key, although that's a wasteful thing to do frequently.

            Originally posted by tildearrow View Post
            I don't use chrono. Instead I use a custom C++ wrapper to struct timespec.
            Um, why? And it doesn't help you, if you need to use something like std::condition_variable::wait_until(), which takes a std::chrono::time_point<> parameter.

            The learning curve on std::chrono is a little steep, but at least it has distinct types for absolute and relative measures of time. Flexibility over types and units is also nice, even if it does feel a bit awkward.

            Originally posted by tildearrow View Post
            I never understood how to use λ's...
            It's an investment that will pay dividends.

            Also, spend some time becoming comfortable with std::bind. It's based on boost::bind, which had a significant impact on the way I write C++. Together, they enable a much more functional style, largely eliminating over-reliance on classes and inheritance.

            Originally posted by tildearrow View Post
            constexpr? I never knew about that.
            There are many C++ features I have never used...
            Well, you could do worse than spend some time reading these:
            In my early years of using C++, I spent the time and read Stroustrup. If you're using it for anything serious, it's worth at least getting down to that level of detail. Scott Meyers' books and C++ Templates: The Complete Guide (Vandevoorde & Josuttis) took my C++ to the next level. Sad to say, Meyers' Effective Modern C++ isn't as approachable as his earlier works, but those are pre-C++11.

            Originally posted by tildearrow View Post
            I only use C arrays for fixed-size ones or when I really desire speed. Otherwise I use std::vector
            The point of std::array is to give you a convenient container interface with the same speed & constraints as a C array.

            A big part of being a competent C++ programmer is learning the right container to use for the job.
            Last edited by coder; 30 September 2019, 10:24 PM.

            Comment


            • #36
              Originally posted by AsuMagic View Post
              At their simplest level, they allow you to define compile time constants so you don't have to deal with macros.
              Heh, you'll never be truly rid of macros. Just try writing assert() without using macros, to give one use case.

              Comment


              • #37
                As a Lisp user, my mind boggles at how you C++ programmers survived without lambda expressions. For people who are curious, they are just unnamed procedures that evaluate to a value. (aka function expressions)

                Here’s a procedure in Scheme:
                Code:
                (define (square x) (* x x))
                This is actually syntax sugar, which, when desugared, reveals the lambda magic!
                Code:
                (define square [B](lambda (x) (* x x))[/B])
                And of course the name is entirely unnecessary to use it.
                Code:
                ((lambda (x) (* x x)) 5)
                JavaScript also has a really fantastic syntax for them.
                Code:
                const square = (x) => x * x
                Code:
                [1, 2, 3, 4, 5].reduce((acc, curr) => acc + curr) // equals 15
                Originally posted by coder
                Sad to say, Meyers' Effective Modern C++ isn't as approachable as his earlier works, but those are pre-C++11.
                What do you mean? That book was fantastic! There is a similar tome for Java (I think it’s just called Effective Java) that is equally good, but reminds me precisely why I’d rather use Clojure than Java. The kind of pain and misery you must go through because you are forced to use classes for everything is too much for me, but we live in a better era than when Java was first introduced. (and clearly it was a backlash against C/C++ that went way overboard)

                Comment


                • #38
                  Originally posted by coder View Post
                  Err... you mean erase from vectors? You can overwrite array elements, but you can't erase them.

                  Anyway, if you might need to erase, I think your best options are:
                  • use iterators
                  • iterate by index (if randomly-accessible container)

                  If an associative container, you can also erase by key, although that's a wasteful thing to do frequently.
                  So there is no way to do it using the easily-readable syntax? Oh....

                  Originally posted by coder View Post
                  Um, why? And it doesn't help you, if you need to use something like std::condition_variable::wait_until(), which takes a std::chrono::time_point<> parameter.

                  The learning curve on std::chrono is a little steep, but at least it has distinct types for absolute and relative measures of time. Flexibility over types and units is also nice, even if it does feel a bit awkward.
                  Because I use clock_gettime since I think it takes less time to execute.

                  Originally posted by coder View Post
                  It's an investment that will pay dividends.

                  Also, spend some time becoming comfortable with std::bind. It's based on boost::bind, which had a significant impact on the way I write C++. Together, they enable a much more functional style, largely eliminating over-reliance on classes and inheritance.


                  Well, you could do worse than spend some time reading these:
                  In my early years of using C++, I spent the time and read Stroustrup. If you're using it for anything serious, it's worth at least getting down to that level of detail. Scott Meyers' books and C++ Templates: The Complete Guide (Vandevoorde & Josuttis) took my C++ to the next level. Sad to say, Meyers' Effective Modern C++ isn't as approachable as his earlier works, but those are pre-C++11.


                  The point of std::array is to give you a convenient container interface with the same speed & constraints as a C array.

                  A big part of being a competent C++ programmer is learning the right container to use for the job.
                  OK, thank you. I really never thought C++ was this vast.

                  Comment


                  • #39
                    Originally posted by cynical View Post
                    As a Lisp user, my mind boggles at how you C++ programmers survived without lambda expressions.
                    Us Boost-users had them for quite a while:

                    https://www.boost.org/doc/libs/1_31_...doc/index.html


                    And even before Boost introduce boost::bind(), STL had bind1st() and bind2nd():

                    https://www.boost.org/doc/libs/1_31_...bind/bind.html
                    https://en.cppreference.com/w/cpp/ut...ctional/bind12


                    Plus, for a lot of generic operations, we had pre-defined function templates:


                    (note the number of operations lacking version qualifiers)


                    But, before/besides that, it just meant that using generic algorithms and higher-order operations required writing a few more one-off functions and functors.

                    Originally posted by cynical View Post
                    JavaScript also has a really fantastic syntax for them.
                    One of its saving graces. But, it's not hard to find flagrant overuse/abuse of lambdas, in Javascript. While AJAX code is immensely helped by them, it's not uncommon to see most of a source file written in lambdas.

                    Originally posted by cynical View Post
                    What do you mean? That book was fantastic!
                    I didn't say it wasn't good. However, from the beginning, it seems to veer straight into language laywering, before it really starts to pay off (IIRC). That could be off-putting for some, but it's definitely worth pushing through.

                    My recollection is that his earlier C++ books started with a much more gentle tone, offering advice you can use straight away.

                    Comment


                    • #40
                      Originally posted by tildearrow View Post
                      So there is no way to do it using the easily-readable syntax? Oh....
                      See AsuMagic 's point about iterator invalidation. That's where you have to be careful, no matter how you're iterating.

                      Remember, they're called "range-based for-loops", for a reason. It's interesting to dig under the covers and see how the language implements them, if you're curious.

                      If your use case didn't involve modifying the container, you could maintain an index on the side. I'm sure I've done that, but I'm having a bit of trouble thinking of a good example of when it's needed.

                      Anyway, an important part of choosing the right container for your purpose is considering the circumstances under which its iterators are invalidated. For example, list insertions and removals don't affect iterators other than those to the element being removed. However, pretty much any operation changing a vector's size will invalidate its iterators.

                      Originally posted by tildearrow View Post
                      Because I use clock_gettime since I think it takes less time to execute.
                      Really? I figure std::chrono::system_clock::now() should be just a thin wrapper around it:

                      https://en.cppreference.com/w/cpp/ch...stem_clock/now

                      If you can quantify any significant overhead, do let us know.

                      Comment

                      Working...
                      X