[Development] Notes from "C++17 language and std library features for Qt 6"
Kari Oikarinen
kari.oikarinen at qt.io
Wed Nov 20 20:27:36 CET 2019
I managed to mangle copy pasting to the mail, so probably better to read
from the wiki page rather than read everything twice in a tricky order.
On 20.11.2019 21.20, Kari Oikarinen wrote:
> Hi!
>
> Here are the notes for the C++17 related session held today at QtCS. I
> tried my best to capture the discussion, but there might still be a lot
> of errors.
>
> Notes are also in the wiki at
> https://wiki.qt.io/Qt_Contributor_Summit_2019_-_C%2B%2B17_Features_Notes
>
> # Language
>
>
> ## if constexpr
>
> # Language
>
>
> ## if constexpr
>
> Very useful for our containers.
>
>
> ## Fold expressions
>
> Shortcut for handling parameter packs of vadiadic templates. No need
> to write recursive template helpers.
>
>
> ## Inline variable
>
> Volker: What is the impact of using inline variables to static data
> initialization? How do we deal with `Q_GLOBAL_STATIC`?
>
> Inline variables are safer than static globals. Compiler and linker
> guarantee that there will be just one definition.
>
> `Q_GLOBAL_STATIC` still provides lazy initialization. So inline
> variables are not a full replacement. Any big globals that aren't
> necessarily used should be gated by lazy initialization to avoid
> constructing them unnecessarily.
>
>
> ## Polymorphic lambdas
>
> What is it? It has auto as its parameter type. So the same lambda can
> be used with multiple invocations with parameters of different types.
>
> Most common use is just for brevity. It gives you perfect forwarding
> as well, if you use auto && as the type.
>
> But these are not API visible, just perhaps useful inside the
> implementation.
>
>
> ## Structured bindings
>
> QRect and QPoint might be possible candidates. But there will not be
> many that this makes sense for.
>
> Some of these will already be aggregates and work automatically. But
> perhaps they for example have user-defined constructors and so don't
> fulfill the requirements of that.
>
>
> ## Language attributes
>
> There are macros for many standard attributes, like nodiscard,
> deprecated, fallthrough, likely and unlikely.
>
> When is the right point to remove this macros and use the attributes
> directly? When all compilers support it. Although that causes pain
> when backporting to older branches.
>
> That applies to all language features, though. Some backporting is
> really hairy, like converting if constexpr solutions back to template
> specializations.
>
>
> ## Modules (C++20)
>
> Properly modularizing Qt is going to be a huge undertaking. There
> should be some prototyping done by an energetic volunteer.
>
> There are rumors that moc generated code leads to some issues here.
>
> How will `QT_CONFIG()` macros work together with modules? Every
> permutation would need to be shipped as a separate module. But they
> are going to be constant within a built Qt. Not something the user of
> the library can change.
>
> Modules are not supported by build systems (including qmake and CMake)
> yet. CMake developer Kitware is working on it, though.
>
>
> ## Coroutines (C++20)
>
> QDialog::call/exec() are already coroutines, but stackful ones. So
> converting to them stackless is not really possible. But there might
> be better candidates in networking or elsewhere with callbacks.
>
> Standard coroutines are quite cumbersome to use. Would we use an
> external helper library with that or would Qt provide their own helper
> for coroutines? Having Qt-friendly coroutine helpers would be nice.
>
> Test data supplying is currently a huge matrix of QVariants and is
> actually a performance bottleneck for our tests. Using generators for
> these might be helpful? They are not going to make a difference
> compared to a good hand-written generator. So the performance issues
> might be fixed with other approaches.
>
>
> # Library
>
> Contributions to any of these would be welcome.
>
>
> ## std::any
>
> std::any is like a QVariant that does not need registration.
>
> Could there be conversions between QVariant and std::any? Ville is
> skeptical about how to do that. Olivier suggested adding support for
> conversion from std::any to QVariant into QMetatype. But can that be
> done with just a reference to `std::type_info`?
>
> std::any is a replacement for void\*. It knows the type that it holds.
>
>
> ## std::filesystem
>
> Giuseppe: Should be use std::filesystem::path types consistently in
> our APIs instead of QString? Ville: There should be a prototype patch
> to see how big the effect is. I'm concerned that the impact would be
> too big.
>
> Is std::filesystem::path API stable enough? Standard committee cares
> about API stability a lot, so that's not a worry. Although some want a
> new version of the API that uses std::expected.
>
>
> ## Parallel STL algorithms
>
> We could allow parallel execution tags in our API to let users ask for
> use of parallel algorithms.
>
> But what are the places in Qt API that actually need these? More data
> analysis stuff (if developed) would find it helpful. But often users
> get to choose their own algorithms and so can use parallel algorithms
> without our containers needing to know about it.
>
> If a parallel STL implementation is not available, falling back to
> single-threaded implementation is always an option. So support could
> be utilized only when available and not demanded from all platforms.
> Or the platfrom support can be a shim that still always processes
> everything without parallelism.
>
>
> ## `std::unique_ptr`
>
> Better support for `std::unique_ptr` for Qt APIs?
>
> A patch for more explicit ownership for QObject hierarchy has been
> suggested in the past. Maybe out of scope for this session.
> `std::unique_ptr` is not new in C++17.
>
>
> ## std::optional
>
> Would it be worth changing API to return std::optionals instead of
> bool output parameters? It would be a big source-incompatible change.
>
>
> ## `std::string_view`
>
> Do we want to use `std::string_view`? Or do we need a QByteArrayView?
> In order to match QByteArray API?
>
> Will QByteArray still be for string data in Qt 6? That's a topic for
> tomorrows session.
>
> QByteArray has some API that expects the contents to be string-like.
> Unfortunately, because they don't really belong there. QByteArray's
> future should be clarified before making decisions about these can be
> made.
>
>
> ## std::format (C++20)
>
> Not available to us yet. And will work with `std::basic_string` only
> pretty much. Not with QString.
>
>
> # Co-operation with compiler vendors
>
> Ville has talked to INTEGRITY multiple times. Technically they can
> provide a C++17 compatible compiler due to using IDG frontend. They
> haven't provided a timeline when that is actually released.
>
> Embedded (and other) platforms that don't provide C++17 launch will be
> initially dropped from being supported. They will be added later once
> their compilers catch up.
>
> QNX has gcc-based compiler so they should also be able to update their
> systems.
>
>
> # Testing
>
> Testlib feels old and unfriendly. Reflection is the real killer
> feature for nice testing. It would allow much less macro use and other
> boilerplate. It's also the solution for everything else.
>
>
> # Getting rid of moc
>
> Reflection should also replace moc at some point.
>
> Andrew (one of the reflection proposal authors) is working on
> something very moc-like and would like feedback from the Qt community.
> So far he has not gotten any. People who know our metaobject system
> well should engage with standard committee members so that the final
> reflection solution will serve us well. Ville Voutilainen is one
> possible contact point in addition to Andrew Sutton.
>
>
> # Replacing conditional compilation flags with if constexpr
>
> if constexpr demands that all branches are valid. Other branch can
> only not compile when it is inside a template.
>
> Conditional compilation still needs the preprocessor, because if a
> feature is disabled, the branch using it would not be valid code.
>
>
> # Minimum compiler versions for 6.0
>
> Lars had a proposal on the mailing list and there has been no
> opposition.
>
> The set of minimum versions would be:
>
> - GCC 9
> - Clang 9
> - Apple Clang 11 (Clang 9)
> - MSVC 2019
>
> Thiago would like it to be a bit more conservative. But when 6.0 comes
> out, GCC 9 will be one and a half years old. So it's not bleeding
> edge. 18 months old compilers should be fine, but probably not much
> newer than that.
>
> Qt 6 will require C++17. So compiler will be need to switched to C++17
> mode. But users might still be able to have codebases that only use
> C++11, since not much API will necessarily require C++17 features to
> use. So codebases with compatibility for older language versions (in
> other builds) should be largely possible.
>
>
>
> Very useful for our containers.
>
>
> ## Fold expressions
>
> Shortcut for handling parameter packs of vadiadic templates. No need
> to write recursive template helpers.
>
>
> ## Inline variable
>
> Volker: What is the impact of using inline variables to static data
> initialization? How do we deal with `Q_GLOBAL_STATIC`?
>
> Inline variables are safer than static globals. Compiler and linker
> guarantee that there will be just one definition.
>
> `Q_GLOBAL_STATIC` still provides lazy initialization. So inline
> variables are not a full replacement. Any big globals that aren't
> necessarily used should be gated by lazy initialization to avoid
> constructing them unnecessarily.
>
>
> ## Polymorphic lambdas
>
> What is it? It has auto as its parameter type. So the same lambda can
> be used with multiple invocations with parameters of different types.
>
> Most common use is just for brevity. It gives you perfect forwarding
> as well, if you use auto && as the type.
>
> But these are not API visible, just perhaps useful inside the
> implementation.
>
>
> ## Structured bindings
>
> QRect and QPoint might be possible candidates. But there will not be
> many that this makes sense for.
>
> Some of these will already be aggregates and work automatically. But
> perhaps they for example have user-defined constructors and so don't
> fulfill the requirements of that.
>
>
> ## Language attributes
>
> There are macros for many standard attributes, like nodiscard,
> deprecated, fallthrough, likely and unlikely.
>
> When is the right point to remove this macros and use the attributes
> directly? When all compilers support it. Although that causes pain
> when backporting to older branches.
>
> That applies to all language features, though. Some backporting is
> really hairy, like converting if constexpr solutions back to template
> specializations.
>
>
> ## Modules (C++20)
>
> Properly modularizing Qt is going to be a huge undertaking. There
> should be some prototyping done by an energetic volunteer.
>
> There are rumors that moc generated code leads to some issues here.
>
> How will `QT_CONFIG()` macros work together with modules? Every
> permutation would need to be shipped as a separate module. But they
> are going to be constant within a built Qt. Not something the user of
> the library can change.
>
> Modules are not supported by build systems (including qmake and CMake)
> yet. CMake developer Kitware is working on it, though.
>
>
> ## Coroutines (C++20)
>
> QDialog::call/exec() are already coroutines, but stackful ones. So
> converting to them stackless is not really possible. But there might
> be better candidates in networking or elsewhere with callbacks.
>
> Standard coroutines are quite cumbersome to use. Would we use an
> external helper library with that or would Qt provide their own helper
> for coroutines? Having Qt-friendly coroutine helpers would be nice.
>
> Test data supplying is currently a huge matrix of QVariants and is
> actually a performance bottleneck for our tests. Using generators for
> these might be helpful? They are not going to make a difference
> compared to a good hand-written generator. So the performance issues
> might be fixed with other approaches.
>
>
> # Library
>
> Contributions to any of these would be welcome.
>
>
> ## std::any
>
> std::any is like a QVariant that does not need registration.
>
> Could there be conversions between QVariant and std::any? Ville is
> skeptical about how to do that. Olivier suggested adding support for
> conversion from std::any to QVariant into QMetatype. But can that be
> done with just a reference to `std::type_info`?
>
> std::any is a replacement for void\*. It knows the type that it holds.
>
>
> ## std::filesystem
>
> Giuseppe: Should be use std::filesystem::path types consistently in
> our APIs instead of QString? Ville: There should be a prototype patch
> to see how big the effect is. I'm concerned that the impact would be
> too big.
>
> Is std::filesystem::path API stable enough? Standard committee cares
> about API stability a lot, so that's not a worry. Although some want a
> new version of the API that uses std::expected.
>
>
> ## Parallel STL algorithms
>
> We could allow parallel execution tags in our API to let users ask for
> use of parallel algorithms.
>
> But what are the places in Qt API that actually need these? More data
> analysis stuff (if developed) would find it helpful. But often users
> get to choose their own algorithms and so can use parallel algorithms
> without our containers needing to know about it.
>
> If a parallel STL implementation is not available, falling back to
> single-threaded implementation is always an option. So support could
> be utilized only when available and not demanded from all platforms.
> Or the platfrom support can be a shim that still always processes
> everything without parallelism.
>
>
> ## `std::unique_ptr`
>
> Better support for `std::unique_ptr` for Qt APIs?
>
> A patch for more explicit ownership for QObject hierarchy has been
> suggested in the past. Maybe out of scope for this session.
> `std::unique_ptr` is not new in C++17.
>
>
> ## std::optional
>
> Would it be worth changing API to return std::optionals instead of
> bool output parameters? It would be a big source-incompatible change.
>
>
> ## `std::string_view`
>
> Do we want to use `std::string_view`? Or do we need a QByteArrayView?
> In order to match QByteArray API?
>
> Will QByteArray still be for string data in Qt 6? That's a topic for
> tomorrows session.
>
> QByteArray has some API that expects the contents to be string-like.
> Unfortunately, because they don't really belong there. QByteArray's
> future should be clarified before making decisions about these can be
> made.
>
>
> ## std::format (C++20)
>
> Not available to us yet. And will work with `std::basic_string` only
> pretty much. Not with QString.
>
>
> # Co-operation with compiler vendors
>
> Ville has talked to INTEGRITY multiple times. Technically they can
> provide a C++17 compatible compiler due to using IDG frontend. They
> haven't provided a timeline when that is actually released.
>
> Embedded (and other) platforms that don't provide C++17 launch will be
> initially dropped from being supported. They will be added later once
> their compilers catch up.
>
> QNX has gcc-based compiler so they should also be able to update their
> systems.
>
>
> # Testing
>
> Testlib feels old and unfriendly. Reflection is the real killer
> feature for nice testing. It would allow much less macro use and other
> boilerplate. It's also the solution for everything else.
>
>
> # Getting rid of moc
>
> Reflection should also replace moc at some point.
>
> Andrew (one of the reflection proposal authors) is working on
> something very moc-like and would like feedback from the Qt community.
> So far he has not gotten any. People who know our metaobject system
> well should engage with standard committee members so that the final
> reflection solution will serve us well. Ville Voutilainen is one
> possible contact point in addition to Andrew Sutton.
>
>
> # Replacing conditional compilation flags with if constexpr
>
> if constexpr demands that all branches are valid. Other branch can
> only not compile when it is inside a template.
>
> Conditional compilation still needs the preprocessor, because if a
> feature is disabled, the branch using it would not be valid code.
>
>
> # Minimum compiler versions for 6.0
>
> Lars had a proposal on the mailing list and there has been no
> opposition.
>
> The set of minimum versions would be:
>
> - GCC 9
> - Clang 9
> - Apple Clang 11 (Clang 9)
> - MSVC 2019
>
> Thiago would like it to be a bit more conservative. But when 6.0 comes
> out, GCC 9 will be one and a half years old. So it's not bleeding
> edge. 18 months old compilers should be fine, but probably not much
> newer than that.
>
> Qt 6 will require C++17. So compiler will be need to switched to C++17
> mode. But users might still be able to have codebases that only use
> C++11, since not much API will necessarily require C++17 features to
> use. So codebases with compatibility for older language versions (in
> other builds) should be largely possible.
>
--
Kari
More information about the Development
mailing list