diff options
author | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2022-04-06 16:39:22 +0200 |
---|---|---|
committer | Giuseppe D'Angelo <giuseppe.dangelo@kdab.com> | 2022-04-11 23:26:00 +0200 |
commit | e9962537743333059b4857ce63e9888cb9591774 (patch) | |
tree | 8f7070b91cbd2159f8dd8e862fcbb5ae223ce958 | |
parent | 251e9f0bed6dd0206cc430365b6c6653f78969e1 (diff) |
Add a marker for post-C++17 APIs in exported classes
MSVC will export any function in an exported class, including inline
ones. Conversely: client code calling inline functions in imported
classes will end up simply calling the symbol of the function, even if
the function is fully inline.
This is a problem for adding post-C++17 APIs in Qt. Such APIs are added
as inline functions protected by feature-macro tests, so that both Qt
and client apps can use any C++ version they want (any combination
works).
However, if we add a function using post-C++17 API to an exported class,
then the combination "Qt built in C++17" + "client built in post-C++17"
won't work any more. The client will expect the symbol for that function
to be exported by Qt, but Qt won't have it (built in C++17).
As a workaround, add a marker that turns these functions into "faux
templates", like Q_WEAK_OVERLOAD does.
Change-Id: I2adab81e3129c881c5a8e0772948b176fa4db1b6
Reviewed-by: Thiago Macieira <thiago.macieira@intel.com>
-rw-r--r-- | doc/global/qt-cpp-defines.qdocconf | 1 | ||||
-rw-r--r-- | src/corelib/global/qcompilerdetection.h | 20 |
2 files changed, 21 insertions, 0 deletions
diff --git a/doc/global/qt-cpp-defines.qdocconf b/doc/global/qt-cpp-defines.qdocconf index 5c762083a2..c2a267d08e 100644 --- a/doc/global/qt-cpp-defines.qdocconf +++ b/doc/global/qt-cpp-defines.qdocconf @@ -162,6 +162,7 @@ Cpp.ignoretokens += \ QT_FASTCALL \ QT_MUTEX_LOCK_NOEXCEPT \ QT_POPCOUNT_CONSTEXPR \ + QT_POST_CXX17_API_IN_EXPORTED_CLASS \ QT_SIZEPOLICY_CONSTEXPR \ QT_WARNING_DISABLE_DEPRECATED \ QT_WARNING_PUSH \ diff --git a/src/corelib/global/qcompilerdetection.h b/src/corelib/global/qcompilerdetection.h index f6add04fba..1c17e8b7a0 100644 --- a/src/corelib/global/qcompilerdetection.h +++ b/src/corelib/global/qcompilerdetection.h @@ -1207,6 +1207,26 @@ #define Q_WEAK_OVERLOAD template <typename = void> /* + * If one wants to add functions that use post-C++17 APIs, one needs to: + * + * 1) make them fully inline; and + * 2) guard them using the necessary feature-testing macros. + * + * This decouples the C++ version used to build Qt with the one used by + * end-user applications; Qt and the application can either choose any C++ + * version. + * + * A problem arises on MSVC for member functions of exported classes. Client + * code that tries to use such a function will see it as exported, and simply + * try to consume the function's *symbol*. However, if Qt has been built in + * C++17, it won't have such a symbol, and linking will fail. + * + * The workaround: declare such functions as function templates. + * (Obviously a function template does not need this marker.) +*/ +#define QT_POST_CXX17_API_IN_EXPORTED_CLASS template <typename = void> + +/* * Warning/diagnostic handling */ |