Details
-
Suggestion
-
Resolution: Won't Do
-
Not Evaluated
-
None
-
None
-
None
Description
Simply adding a Q_DECL_CONSTEXPR inside QStringLiteral definition like this:
#define QStringLiteral(str) \ ([]() Q_DECL_NOEXCEPT -> QString { \ enum { Size = sizeof(QT_UNICODE_LITERAL(str))/2 - 1 }; \ static const Q_DECL_CONSTEXPR QStaticStringData<Size> qstring_literal = { \ Q_STATIC_STRING_DATA_HEADER_INITIALIZER(Size), \ QT_UNICODE_LITERAL(str) }; \ QStringDataPtr holder = { qstring_literal.data_ptr() }; \ const QString qstring_literal_temp(holder); \ return qstring_literal_temp; \ }()) \ /**/
works fine and heavily reduces binary size at least for MSVC compiler (checked on msvc2017 for x86 with /O2 optimization). I use Qt 5.12.6 and as I see on github - in newer versions nothing has changed.
More brave optimization could be following (though this is pretty hacky and I may be missing something, please correct me in such case):
#define QStringLiteral(str_value) \ ([]() Q_DECL_NOEXCEPT -> const QString& { \ enum { Size = sizeof(QT_UNICODE_LITERAL(str_value))/2 - 1 }; \ static const Q_DECL_CONSTEXPR QStaticStringData<Size> qstring_literal = { \ Q_STATIC_STRING_DATA_HEADER_INITIALIZER(Size), \ QT_UNICODE_LITERAL(str_value) }; \ static const QStringData* ptr = static_cast<const QStringData*>(&qstring_literal.str); \ return *reinterpret_cast<const QString*>(&ptr); \ }())
this somewhat unwraps existing conversions and allows returning QString by reference which is more optimal in most use-cases, as most functions accept a const reference to QString. When QString is returned by value but receiver accepts reference - redundant temporary object is created, thus extra destrucor call, extra exception-handler code is generated, extra performance degradation (though very minor). This version reduces my project binary even more.