Re: [Development] QProperty and library coding guide
On Friday, 24 July 2020 10:32:08 PDT Ville Voutilainen wrote: > I don't know what the "sub-scope of a class" means. struct S { namespace prop1 { int operator()() const; void bind(std::function binding; }; private: int propvalue; } int S::prop1::operator()() const { static_assert(std::is_same_v); return propvalue; } int f(S *s) { s->prop1.bind([](int) {}); return s->prop1(); } -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel DPG Cloud Engineering ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Fri, 24 Jul 2020 at 22:24, Lisandro Damián Nicanor Pérez Meyer wrote: > > A few years ago, Gtk threatened to do that starting with Gtk 4: > > https://lwn.net/Articles/691131/ > > https://blogs.gnome.org/desrt/2016/06/13/gtk-4-0-is-not-gtk-4/ > > https://blogs.gnome.org/desrt/2016/06/14/gtk-5-0-is-not-gtk-5/ > > > > They changed their minds. > > When those news arose we Qt maintainers felt really really happy that > we maintain Qt, and that's because of BC. > > Qt is already too big to maintain, especially if you are not being > paid for it. Break BC often and finding distro maintainers will be the > hardest thing to do. +1. Frequent BC breaks end up hurting end users, in addition to developers and packagers. They are going to walk, and the developers will follow. ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
Hi! With my Debian Qt maintainer hat on: I want to stress everything that Thiago mentioned in the cited below mail. Rebuilding the entire Qt world in a distribution is a tremendous huge task. I'm afraid I can't express the pain it is specially for libraries as popular as Qt... try it yourself maybe? Change the SONAME and restart building Debian unstable. Don't forget that that means the whole set of architectures too. Oh, and that needs to be as fast as possible, Qt is so central in many things that other stuff will end up waiting for it to finish. Example: poppler can't be updated in the meantime. And that's just poppler. On Thu, 23 Jul 2020 at 19:11, Thiago Macieira wrote: [snip] > > In any case, I don't think either use case is an absolute reason for keeping > > BC. > > It's a choice. > > But I warn against choosing to break too often. > > A few years ago, Gtk threatened to do that starting with Gtk 4: > https://lwn.net/Articles/691131/ > https://blogs.gnome.org/desrt/2016/06/13/gtk-4-0-is-not-gtk-4/ > https://blogs.gnome.org/desrt/2016/06/14/gtk-5-0-is-not-gtk-5/ > > They changed their minds. When those news arose we Qt maintainers felt really really happy that we maintain Qt, and that's because of BC. Qt is already too big to maintain, especially if you are not being paid for it. Break BC often and finding distro maintainers will be the hardest thing to do. -- Lisandro Damián Nicanor Pérez Meyer http://perezmeyer.com.ar/ http://perezmeyer.blogspot.com/ ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Fri, 24 Jul 2020 at 18:10, Thiago Macieira wrote: > Can I suggest that we prepare at least two papers for the standard? One for > the member-to-containing-object trick and the second for what QProperty really > is: sub-scope of a class. We don't want a different this pointer, we just want > to scope. The member-to-containing-object seems like it might just be a fix to what P1839 says. I don't know what the "sub-scope of a class" means. ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Friday, 24 July 2020 08:27:54 PDT Stottlemyer, Brett (B.S.) wrote: > ... what QProperty really > is: sub-scope of a class. We don't want a different this pointer, we > just want to scope. > > Is QProperty really a sub-scope? Many of the examples are not tied to > objects (QObject or otherwise) at all. See > https://code.qt.io/cgit/qt/qtbase.git/tree/tests/auto/corelib/kernel/qprope > rty/tst_qproperty.cpp#n90. > I'm guessing you are likely talking specifically about the > Q_PROPERTY_PRIVATE macro specifically, just want to make sure. Yes, sorry. I really meant that. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel DPG Cloud Engineering ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On 7/24/20, 11:09 AM, "Development on behalf of Thiago Macieira" wrote: ... what QProperty really is: sub-scope of a class. We don't want a different this pointer, we just want to scope. Is QProperty really a sub-scope? Many of the examples are not tied to objects (QObject or otherwise) at all. See https://code.qt.io/cgit/qt/qtbase.git/tree/tests/auto/corelib/kernel/qproperty/tst_qproperty.cpp#n90. I'm guessing you are likely talking specifically about the Q_PROPERTY_PRIVATE macro specifically, just want to make sure. Brett ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Friday, 24 July 2020 00:20:46 PDT Olivier Goffart wrote: > You do not need to use the empty array everywhere: only in the helper type > created by the Q_PRIVATE_QPROPERTY macro. And it can be conditioned on > pre-c++20 GCC. The problem is that it is in QObject and other Qt classes. That's why I meant "everywhere". See its warnings with -pedantic: https://godbolt.org/z/cYbbG3 though of course it can be disabled: https://godbolt.org/z/zdbePj This feature is GCC's extension that was there prior to C99 Flexible Array Members (FAMs use x[] as a syntax, not x[0]). As an extension that has been superseded, it can disappear at any time. Though I'll grant you again that a future compiler that does disappear it is one that will support [[no_unique_address]]. In all, I think we have enough workarounds for this, for past compilers. Can I suggest that we prepare at least two papers for the standard? One for the member-to-containing-object trick and the second for what QProperty really is: sub-scope of a class. We don't want a different this pointer, we just want to scope. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel DPG Cloud Engineering ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
Yes. QNX 7.1 is based on GCC 8. On 2020-07-23, 5:03 PM, "Development on behalf of Ville Voutilainen" wrote: On Thu, 23 Jul 2020 at 23:59, Thiago Macieira wrote: > > On Thursday, 23 July 2020 12:34:06 PDT Simon Hausmann wrote: > > I think the primary environment where a transition and resulting BC > > breakage would be annoying is the Linux system environment with gcc. This > > is where Olivier’s solution is quite elegant IMO. > > I'd rather go to [[no_unique_address]] instead of this. The extension doesn't > compile in all cases (you can't have a Flexible Array Member everywhere) and > is going to produce warnings. > > Let's just drop GCC 8. Does that also drop QNX? ___ Development mailing list Development@qt-project.org https://urldefense.proofpoint.com/v2/url?u=https-3A__lists.qt-2Dproject.org_listinfo_development&d=DwIGaQ&c=yzoHOc_ZK-sxl-kfGNSEvlJYanssXN3q-lhj0sp26wE&r=HB7_zq-d1V3WeAdNGC_by-Ou7WOmkfxFMKVYxGfHYTs&m=r18UENxUZTmc76lNsEaKZHWxuRz8_WqA1QHOOv4pzp0&s=VJjTNtXQ7lCGy8n1vheFyE79PiQeQcPJ1dHOSsLYh9I&e= -- This transmission (including any attachments) may contain confidential information, privileged material (including material protected by the solicitor-client or other applicable privileges), or constitute non-public information. Any use of this information by anyone other than the intended recipient is prohibited. If you have received this transmission in error, please immediately reply to the sender and delete this information from your system. Use, dissemination, distribution, or reproduction of this transmission by unintended recipients is not authorized and may be unlawful. ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On 23/07/20 22:54, Thiago Macieira wrote: On Thursday, 23 July 2020 12:34:06 PDT Simon Hausmann wrote: I think the primary environment where a transition and resulting BC breakage would be annoying is the Linux system environment with gcc. This is where Olivier’s solution is quite elegant IMO. I'd rather go to [[no_unique_address]] instead of this. The extension doesn't compile in all cases (you can't have a Flexible Array Member everywhere) and is going to produce warnings. Let's just drop GCC 8. You do not need to use the empty array everywhere: only in the helper type created by the Q_PRIVATE_QPROPERTY macro. And it can be conditioned on pre-c++20 GCC. And I did not see any warning on compiler explorer. For reference, here is the proposed solution: class MyClass : public QObject { // Generated by QT_PRIVATE_QPROPERTY struct _qt_property_api_foo { QString operator()(); void setValue(const QString &); // ... more functions ... char empty_array[0]; // That's a GCC extension }; _qt_property_api_foo foo; }; ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Thursday, 23 July 2020 15:10:23 PDT Thiago Macieira wrote: > Strictly speaking, drop GCC 8 for Linux. For other OSes where Qt is not a > system library it could remain. Correcting myself again: drop GCC 8 and Clang 8 (and all previous versions) for Linux and the open source BSDs with a Ports tree. I don't know how to decide about HomeBrew or MacPorts for Mac. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel DPG Cloud Engineering ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Thursday, 23 July 2020 14:03:54 PDT Ville Voutilainen wrote: > > I'd rather go to [[no_unique_address]] instead of this. The extension > > doesn't compile in all cases (you can't have a Flexible Array Member > > everywhere) and is going to produce warnings. > > > > Let's just drop GCC 8. > > Does that also drop QNX? Strictly speaking, drop GCC 8 for Linux. For other OSes where Qt is not a system library it could remain. But in practical terms, it will be hard to keep from using GCC 9 features in our libraries. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel DPG Cloud Engineering ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Thursday, 23 July 2020 08:33:39 PDT André Pönitz wrote: > If Qt would bump major versions once a year, and take that as a chance to > break BC, would that be a problem, if so, why? Let's assume Qt remains strictly source compatible, not even by removing deprecations. That means we can only do minor fixes, like adjusting data members and internal details. Pretty much like Boost and LLVM do. And unlike Boost, we'd also make all files co-installable, including development files (no unversioned binaries in /usr/bin). That would mean every single application, library and plugin would need to be recompiled. No exceptions. Any plugin that isn't recompiled cannot be loaded by the host application that is recompiled. Similarly, the application that wasn't recompiled can't load plugins that were. That completely impedes distribution of software in binary form only. So let's stipulate that we don't care about non-Open Source Qt applications on Linux. It's still a major pain to recompile everything. As a packager in a Linux distribution with VERY good automation and access to a lot of computing power to recompile everything, it's still too difficult to upgrade Boost or Poppler. You have to rebuild the kitchen sink of applications. Some of them fail to rebuild because some other dependency was also updated and is no longer or not yet supported. If one dependency fails to rebuild, what do you do? As a Qt Creator developer, you may have seen my reporting of issues with Qt Creator failing to compile with an LLVM that was released the week prior. And this is with a responsible project like Qt Creator; when I reported an issue to another project that shall remain nameless that "build is broken with LLVM 8, 9 and 10", they replied that I was feeling entitled for support and wasn't their main audience -- I could supply the fix or wait a few years. Another dependency may be the compiler itself: when Clear Linux upgraded from GCC 9 to 10, a BIG NUMBER of packages failed to recompile themselves because GCC changed to -fno-common as the default in C. So rebuilding the world every year is not updating Qt and leaving everything else unchanged. Staying behind is not an option, because some components will require new versions of Qt. Failing to upgrade them may also mean you're out of support for security fixes. So the moment you have one component requiring an update, you have to move the entire system forward. You have to rebuild everything, with the latest dependencies. And you have to do it in one go, since you can't do component-by-component for a period of months. And that was for a distribution that can rebuild the world in a week (Clear Linux has a tenth of the packages in Debian). For distributions without such access to automation and computing power, rebuilding the world every year is a non-starter. Even assuming everything "just builds" which is never the case. Even a perfectly source-compatible update of Qt is no such thing: think of missing #includes. And remember the condition that we do not remove deprecated things. The moment you do, some applications, libraries, frameworks or plugins stop building because they were still using the deprecated API. At best, we'd have to have a policy that we need to wait 5 years between deprecation and removal of anything. > Because distributions have a large set of packages that are not > rebuild at least once a year? Or because users have a few hundred > packages that they don't want to update otherwise? Not the latter. Updating packages that were rebuilt is practically mandatory, given the world of security issues. The problem is building them. > > We've seen users of not-systemwide-Qt-OSes having BC issues too. Large > > projects often have binary artifacts they'd rather not recompile every > > time. > "Every time" would be something as or less frequent than the current minor > release cycles, i.e. twice per year, or less frequent. Agreed, but if you don't rebuild everything every time, you need to have a procedure to determine when to do that and what components you can update in- between those occurrences. So you're adding overhead. The natural conclusion is that they will simply not upgrade the Qt version once a project starts, even for major versions of their products. > > Those teams can be taught to recompile, but that's not their current > > practice. Breaking BC means subtle errors that are hard do detect and > > debug. > Right. But at the same time we accept behaviour changes which can lead to > similar subtle errors that are hard to detect and debug as well. > > I see no real conceptual difference here. It's a choice. Behaviour differences that are meant to be bugfixes are intentional. Unintentional behaviour changes don't often cause data loss and crashes. And when they do, we can often go back and fix the issue (q.v. the QJsonValue::fromVariant thread). A BC break is final. And it often leads to crashes and
Re: [Development] QProperty and library coding guide
On 2020-07-23 23:09, Ville Voutilainen wrote: On Fri, 24 Jul 2020 at 00:03, Ville Voutilainen wrote: On Thu, 23 Jul 2020 at 23:59, Thiago Macieira wrote: On Thursday, 23 July 2020 12:34:06 PDT Simon Hausmann wrote: I think the primary environment where a transition and resulting BC breakage would be annoying is the Linux system environment with gcc. This is where Olivier’s solution is quite elegant IMO. I'd rather go to [[no_unique_address]] instead of this. The extension doesn't compile in all cases (you can't have a Flexible Array Member everywhere) and is going to produce warnings. Let's just drop GCC 8. Does that also drop QNX? It'll also drop mingw for now, unless we start using https://nuwen.net/mingw.html, which is 64-bit only. If you're thinking of mingw on Windows, then there's an other alternative msys2 https://www.msys2.org/ it has gcc 10.1.0 (and it also has fresh downloads of 32-bits and 64-bits Qt Creator 4.12.4 built with 5.15.0 gcc 10.1.0). ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Thursday, 23 July 2020 13:50:26 PDT Bernhard Lindner wrote: > I thought of something like a simple, manually maintained ABI version. Sure, > on the one hand this wouldn't prevent uninentional BC breaks. On the other > hand, BC changes could be done intentionally and managed in a safe way > (without strange crashes). We already have several. See qhooks.cpp's qtHookData[6]: // TypeInformationVersion, an integral value, bumped whenever private // object sizes or member offsets that are used in Qt Creator's // data structure "pretty printing" change. // // The required sizes and offsets are tested in tests/auto/other/ toolsupport. // When this fails and the change was intentional, adjust the test and // adjust this value here. See QObjectPrivate::checkForIncompatibleLibraryVersion(int version). See the ELF versioning trick, which will permit loading Qt 5 and Qt 6 (unnamespaced!) in the same process on ELF systems. See the ability to configure Qt in a namespace and to insert an infix in the library name. I've been using the latter for 7 years: $ ls -1 lib/libQt5Core* lib/libQt5Core.la lib/libQt5Core.t.prl lib/libQt5Core.t.so lib/libQt5Core.t.so.5 lib/libQt5Core.t.so.5.15 lib/libQt5Core.t.so.5.15.0 That way my builds of Qt don't interfere with the Qt-based applications I have in my desktop. It's highly annoying to fix a broken Qt when your desktop is broken. I don't think we need more. Want to make BIC builds? Suit yourself. Here's the gun, the ammo and there's your foot. At best, we could adjust: add the library infix to the ELF version and default to an infix for any non-standard build. symbol _ZN7QObjectC1EPS_@@Qt6.qreal_float.nonouniqueaddress in library libQt6Core.qrealfloat.nonouniqueaddress.so.6 -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel DPG Cloud Engineering ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Fri, 24 Jul 2020 at 00:03, Ville Voutilainen wrote: > > On Thu, 23 Jul 2020 at 23:59, Thiago Macieira > wrote: > > > > On Thursday, 23 July 2020 12:34:06 PDT Simon Hausmann wrote: > > > I think the primary environment where a transition and resulting BC > > > breakage would be annoying is the Linux system environment with gcc. This > > > is where Olivier’s solution is quite elegant IMO. > > > > I'd rather go to [[no_unique_address]] instead of this. The extension > > doesn't > > compile in all cases (you can't have a Flexible Array Member everywhere) and > > is going to produce warnings. > > > > Let's just drop GCC 8. > > Does that also drop QNX? It'll also drop mingw for now, unless we start using https://nuwen.net/mingw.html, which is 64-bit only. ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Thu, 23 Jul 2020 at 23:59, Thiago Macieira wrote: > > On Thursday, 23 July 2020 12:34:06 PDT Simon Hausmann wrote: > > I think the primary environment where a transition and resulting BC > > breakage would be annoying is the Linux system environment with gcc. This > > is where Olivier’s solution is quite elegant IMO. > > I'd rather go to [[no_unique_address]] instead of this. The extension doesn't > compile in all cases (you can't have a Flexible Array Member everywhere) and > is going to produce warnings. > > Let's just drop GCC 8. Does that also drop QNX? ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Thursday, 23 July 2020 12:34:06 PDT Simon Hausmann wrote: > I think the primary environment where a transition and resulting BC > breakage would be annoying is the Linux system environment with gcc. This > is where Olivier’s solution is quite elegant IMO. I'd rather go to [[no_unique_address]] instead of this. The extension doesn't compile in all cases (you can't have a Flexible Array Member everywhere) and is going to produce warnings. Let's just drop GCC 8. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel DPG Cloud Engineering ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
> > Couldn't those subtle errors be replaced by some clear and understandable > > error? Like some explicit binary compatibility check? > > Such a test does not exist, comprehensively. We can put a few common things > in > an ABI marker, like the size of QObject, the actual type qreal maps to, the > name of the C++ standard library we linked against, etc. But that won't catch > everything and it's the minor things that come back to bite you. > > Neither the ABI test by the Linux Foundation, nor abigail, nor our own > tst_bic > are exhaustive. And they're way too slow for a regular run. I thought of something like a simple, manually maintained ABI version. Sure, on the one hand this wouldn't prevent uninentional BC breaks. On the other hand, BC changes could be done intentionally and managed in a safe way (without strange crashes). -- Best Regards, Bernhard Lindner ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
Olivier Goffart schrieb am Fr. 17. Juli 2020 um 19:12: > On 17/07/20 19:00, Thiago Macieira wrote: > > On Friday, 17 July 2020 09:34:54 PDT Lars Knoll wrote: > >>> I'll just post this and let you ponder the consequences of this choice > for > >>> Linux: > >>> https://godbolt.org/z/nhex5x > >> > >> Yes, that’s why we need to encode that into a static_assert(). But the > >> support it coming to all compilers and Linux desktops will support the > >> feature both with gcc and clang. I’m pretty sure ICC will follow soon. > > > > Sure. > > > > But to be clear: we're saying the MINIMUM versions of GCC and Clang for > Qt 6.0 > > are 9.0. GCC 9 was released in May 2019 and LLVM 9 was released in > September > > 2019. > > > > Apple Clang in the current XCode does NOT support it. > > > > Versions of mainstream Linux distributions with GCC 9: > > * Debian: testing > > * Fedora: 30 > > * openSUSE: 15.2 > > * Ubuntu: 19.10 > > (Arch, Clear, Gentoo are rolling releases) > > > > If you're not working from home, go around in the office and ask who's > running > > anything older. > > > > > Maybe use the GCC extension of using an empty array: > > https://godbolt.org/z/MvE9jf > __ I think the primary environment where a transition and resulting BC breakage would be annoying is the Linux system environment with gcc. This is where Olivier’s solution is quite elegant IMO. Simon > ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Wed, Jul 22, 2020 at 10:24:21AM -0700, Thiago Macieira wrote: > On Wednesday, 22 July 2020 09:55:31 PDT André Pönitz wrote: > > How often do we think people are actively taking advantage of Qt's BC > > promise (and how often do we hold this promise, and how often is this > > relevant as we do not promise to change behaviour while keeping BC)? > > That is a good question. I don't want to minimise it, just to add. > > Have at least one category of users that require it, that being the Linux > distributions. > So long as we support them, we have to provide a way to have > BC. And if we do have such a way, how much does it hurt to extend it > everywhere? How much of a *hard* requirement is that in practice? If Qt would bump major versions once a year, and take that as a chance to break BC, would that be a problem, if so, why? Because distributions have a large set of packages that are not rebuild at least once a year? Or because users have a few hundred packages that they don't want to update otherwise? > We've seen users of not-systemwide-Qt-OSes having BC issues too. Large > projects often have binary artifacts they'd rather not recompile every time. "Every time" would be something as or less frequent than the current minor release cycles, i.e. twice per year, or less frequent. > Those teams can be taught to recompile, but that's not their current > practice. > Breaking BC means subtle errors that are hard do detect and debug. Right. But at the same time we accept behaviour changes which can lead to similar subtle errors that are hard to detect and debug as well. I see no real conceptual difference here. > Finally, there's the issue of binary-only components by third parties. If we > ever want to support such an ecosystem (we could call it "Qt Marketplace"), > we > must have as few binary-incompatible versions as possible. It's already > difficult to support, for desktops alone: > - Linux GCC 64-bit > - Apple Clang 64-bit [*] > - Windows MinGW / Clang 32-bit > - Windows MSVC 2019 / clang-cl 32-bit > - Windows MSVC 2019 / clang-cl 64-bit I'll argue that a robust, binary-only distribution of independent, but interacting components does not work in practice. If it would, the Windows ecosystem would have invented that during the last 30 years or so. Instead we have rather monolitic fat applications there, with components shared at most within a given vendor's own product line, with really rare exceptions. > Breaking BC frequently means replicating this table for every BC breakage > level. Or have the input channel accept source code and build the binaries automatically. In any case, I don't think either use case is an absolute reason for keeping BC. Andre' ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Wednesday, 22 July 2020 14:17:26 PDT Bernhard Lindner wrote: > Hi! > > > Breaking BC means subtle errors that are hard do detect and debug. > > Couldn't those subtle errors be replaced by some clear and understandable > error? Like some explicit binary compatibility check? Such a test does not exist, comprehensively. We can put a few common things in an ABI marker, like the size of QObject, the actual type qreal maps to, the name of the C++ standard library we linked against, etc. But that won't catch everything and it's the minor things that come back to bite you. Neither the ABI test by the Linux Foundation, nor abigail, nor our own tst_bic are exhaustive. And they're way too slow for a regular run. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel DPG Cloud Engineering ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
Hi! > Breaking BC means subtle errors that are hard do detect and debug. Couldn't those subtle errors be replaced by some clear and understandable error? Like some explicit binary compatibility check? -- Best Regards, Bernhard Lindner ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Wednesday, 22 July 2020 09:55:31 PDT André Pönitz wrote: > How often do we think people are actively taking advantage of Qt's BC > promise (and how often do we hold this promise, and how often is this > relevant as we do not promise to change behaviour while keeping BC)? That is a good question. I don't want to minimise it, just to add. Have at least one category of users that require it, that being the Linux distributions. So long as we support them, we have to provide a way to have BC. And if we do have such a way, how much does it hurt to extend it everywhere? We've seen users of not-systemwide-Qt-OSes having BC issues too. Large projects often have binary artifacts they'd rather not recompile every time. Those teams can be taught to recompile, but that's not their current practice. Breaking BC means subtle errors that are hard do detect and debug. Finally, there's the issue of binary-only components by third parties. If we ever want to support such an ecosystem (we could call it "Qt Marketplace"), we must have as few binary-incompatible versions as possible. It's already difficult to support, for desktops alone: - Linux GCC 64-bit - Apple Clang 64-bit [*] - Windows MinGW / Clang 32-bit - Windows MSVC 2019 / clang-cl 32-bit - Windows MSVC 2019 / clang-cl 64-bit Breaking BC frequently means replicating this table for every BC breakage level. [*] whether that's a single Universal build or if it is released as separate x86-64 and ARM64 builds remains TBD. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel DPG Cloud Engineering ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Wed, Jul 22, 2020 at 10:27:14AM +, Lars Knoll wrote: > > On 22 Jul 2020, at 11:38, Shawn Rutledge wrote: > > > > > >> On 2020 Jul 16, at 11:19, Ulf Hermann wrote: > >> > >> Data bindings are a cornerstone of most modern UI frameworks, and Qt is > >> actually late to the game. If we want Qt to stay relevant, then it needs to > >> offer the same kind of convenience and performance that other frameworks > >> offer. This would be an argument for converting all existing properties, > >> and > >> paying the price, just to make the binding API available. > > > > Has someone done a survey of how bindings are implemented in other > > frameworks? > > Maybe there is a cool trick out there that we are missing, which would > > enable > > a big leap in efficiency. > > I don’t know of anybody who has done this for C++ yet. I do believe the design > we have with QProperty is pretty good from an API perspective as well as > efficient. > > The problem we’re having purely comes from the fact that we’re trying to > provide > BC between versions and are hiding our data behind a d-pointer. If we'd give > this up the whole problem would go away. Then the elephant in the room is the question how valuable BC in generally is for normal Qt users. How often do we think people are actively taking advantage of Qt's BC promise (and how often do we hold this promise, and how often is this relevant as we do not promise to change behaviour while keeping BC)? For me personally, source compatibility is much more valuable, and BC is a "good enough" approximaton for that insofar that having to keep BC prevents a lot of changes that would also break SC. Andre' ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Wednesday, 22 July 2020 08:52:17 PDT Simon Hausmann wrote: > > On Wednesday, 22 July 2020 00:05:34 PDT Simon Hausmann wrote: > > > That said, this very construct that you're referring to, that is what > > > has been in user > > > code since QtDeclarative was been released [1]. Anybody using > > > qmlRegisterType() will > > > up with local template code that does this. It's impact wise as if moc > > > generated it. > > > > Have you hearad of a Schrödinbug? Not a Heisenbug. > > > > It's a bug that was always there but hurt no one. Until someone noticed > > it. > > Now it will keep reappearing all the time. > > Hehe. Maybe it’s more like a SchödinUB Anyway, I looked at the code in question and though it is UB, it's also optional. It only kicks in if the type being registered multiply-derives from one of three helper classes. Most user-registered types don't. There's also a very simple fix for that. Instead of trying to record the offset in the QML type registry, record the pointer to a function that takes a pointer to QObject and returns the adjusted pointer to those classes. This could have been done in 2010. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel DPG Cloud Engineering ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Wednesday, 22 July 2020 08:50:50 PDT Lars Knoll wrote: > I still don’t understand why you think this should be necessary. All we need > to do is clearly document that enabling/disabling the support for this > feature is not binary compatible and make sure users don’t mix by accident. First, I was talking about the defaults. Are we ok with those defaults? Are we also ok with the communication that goes along with it? I don't want Linux distributions that don't follow Qt development as closely to think they can turn off [[no_unique_address]] support so they can use an older GCC, only to find out later that they can't turn that back on. Second, I don't want the option to turn *off* [[no_unique_address]] in GCC and Clang. We have enough binary applications using Qt that get installed in Linux systems that mixing plugins and libraries is bound to happen, with crashes left and right. I am ok with adding an option to turn it on with MSVC and on Apple OSes, since there's never a system-wide Qt in those. Possibly Android too. So the minimum version of GCC for Linux distributions must be 9.0. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel DPG Cloud Engineering ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
Thiago Macieira schrieb am Mi. 22. Juli 2020 um 17:46: > On Wednesday, 22 July 2020 00:05:34 PDT Simon Hausmann wrote: > > That said, this very construct that you're referring to, that is what > > has been in user > > code since QtDeclarative was been released [1]. Anybody using > > qmlRegisterType() will > > up with local template code that does this. It's impact wise as if moc > > generated it. > > Have you hearad of a Schrödinbug? Not a Heisenbug. > > It's a bug that was always there but hurt no one. Until someone noticed > it. > Now it will keep reappearing all the time. Hehe. Maybe it’s more like a SchödinUB ;-) > > PS: you sent the email to me alone. Did you mean to? > Ooops that was not intentional:) Simon > ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
> On 22 Jul 2020, at 17:30, Thiago Macieira wrote: > > On Wednesday, 22 July 2020 03:24:30 PDT Lars Knoll wrote: >> no_unique_address is coming and making that problem go away. It’s available >> on all compilers except MSVC today (see >> https://en.cppreference.com/w/cpp/compiler_support#cpp2a). >> >> We want things to work on C++17 and that’s what we have. But we can and >> should plan for C++20. > > Please reconfirm you are willing to: > > a) require GCC 9.0 and Clang 9.0 > b) not use [[no_unique_address]] in MSVC and clang-cl until Qt 7 > c) drop support for any other compilers until they support > [[no_unique_address]] > > (I think we only have two other supported compilers: Green Hills' and Intel's) I still don’t understand why you think this should be necessary. All we need to do is clearly document that enabling/disabling the support for this feature is not binary compatible and make sure users don’t mix by accident. Cheers, Lars > -- > Thiago Macieira - thiago.macieira (AT) intel.com > Software Architect - Intel DPG Cloud Engineering > > > > ___ > Development mailing list > Development@qt-project.org > https://lists.qt-project.org/listinfo/development ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Wednesday, 22 July 2020 03:24:30 PDT Lars Knoll wrote: > no_unique_address is coming and making that problem go away. It’s available > on all compilers except MSVC today (see > https://en.cppreference.com/w/cpp/compiler_support#cpp2a). > > We want things to work on C++17 and that’s what we have. But we can and > should plan for C++20. Please reconfirm you are willing to: a) require GCC 9.0 and Clang 9.0 b) not use [[no_unique_address]] in MSVC and clang-cl until Qt 7 c) drop support for any other compilers until they support [[no_unique_address]] (I think we only have two other supported compilers: Green Hills' and Intel's) -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel DPG Cloud Engineering ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On 16-07-2020 17:40, Volker Hilsheimer wrote: We need “text” to be a public member of QAction, otherwise we can’t do action->text(); That ‘text” member is a struct with a bunch of operators overloaded, so that we can do either qDebug() << action->text(); qDebug() << action->text; and action->setText(“foo”); // no binding action->text = document->title; // still no binding action->text = Qt::makePropertyBinding(document->title); // yay binding! Thank you for this example of how these new properties are going to look from a user code perspective. I have some questions left if you don't mind? First, say I have another QProperty that has a binding to this action->text property. I assume that doing `action->setText("foo")` or `action->text = document->title()` will both result in this binding being triggered, and thus, triggering side-effects? I would expect such in the first case, but not so much in the second as this _looks_ like an assignment to a member variable. Second, say that I initialized action->text like you do in your last example, creating a binding. And then I assign to it using, say, `action->text = document->title();` Does that work? Do we overwrite the binding? Is it possible to prevent that override? This was a problem in QML as well where one could accidentally overwrite bindings. I assume there is a way to mimic adding `readonly` like you can in QML? Third, you show that `qDebug() << action.text()` and `qDebug() << action.text` is the same. Is that really all that desirable? Somebody already pointed out this issues with doing an `auto actionText = action.text();` elsewhere in this thread, and I am wondering if you'd not want to output some debug info on the property itself, in stead of just the value? Don't get me wrong: I think the syntax where you're basically able to use the property as if it was a member variable, basically coming back full circle. But I also think it may be confusing for everyone expecting an assignment to something that looks like a member to, well, behave like that. Is there a reason why this setup was chosen over a more conventional but admittedly less cool: action->text->set("foo"); action->text->set(document->title->get()); action->text->bind(document->title); qDebug() << action->text.get(); Cheers, André ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
> On 22 Jul 2020, at 11:38, Shawn Rutledge wrote: > > >> On 2020 Jul 16, at 11:19, Ulf Hermann wrote: >> >> Data bindings are a cornerstone of most modern UI frameworks, and Qt is >> actually late to the game. If we want Qt to stay relevant, then it needs to >> offer the same kind of convenience and performance that other frameworks >> offer. This would be an argument for converting all existing properties, and >> paying the price, just to make the binding API available. > > Has someone done a survey of how bindings are implemented in other > frameworks? Maybe there is a cool trick out there that we are missing, which > would enable a big leap in efficiency. I don’t know of anybody who has done this for C++ yet. I do believe the design we have with QProperty is pretty good from an API perspective as well as efficient. The problem we’re having purely comes from the fact that we’re trying to provide BC between versions and are hiding our data behind a d-pointer. If we'd give this up the whole problem would go away. Cheers, Lars > > Do you have links to docs for the ones that you think look elegant? > > ___ > Development mailing list > Development@qt-project.org > https://lists.qt-project.org/listinfo/development ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On 22 Jul 2020, at 00:14, Ville Voutilainen mailto:ville.voutilai...@gmail.com>> wrote: On Wed, 22 Jul 2020 at 00:18, Volker Hilsheimer mailto:volker.hilshei...@qt.io>> wrote: With the current design, notational convenience doesn’t work either: auto text = qAction->text; text.left(10); // booh ‘text’ is not a QString, but a QAction::_qt_property_api_text object, with broken... everythings. And if people can’t use auto, then you can’t use standard ranged-for to iterate over container type properties without spelling everyhing out. That’s ... not convenient, I suppose. And that problem persists, even if we expose a e.g QProperty reference through a public property member. Couldn't we add operator-> and begin/end to the property type? Yes, there are ways to solve at least part of those issues. Using auto together with those properties is something to consider. But I don’t think we should throw away the whole concept because of it. We can partly solve it by e.g. making the properties not copyable. And we do have similar problems other places (and so does the STL btw). We e.g. need qAsConst() when using our containers with ranged-for our containers. But IMO that is no reason to throw the baby out with the bath-tub water. The current implementation also adds, in case of us not being able to use no_unique_address, a byte or even a pointer to each class in a class hierarchy, bloating classes down in the inheritance tree. Plus the BC challenge that might come with in the long run. So, this is not only a problem of UB. There is well defined behavior that seems to get in the way. Ack. no_unique_address is coming and making that problem go away. It’s available on all compilers except MSVC today (see https://en.cppreference.com/w/cpp/compiler_support#cpp2a). We want things to work on C++17 and that’s what we have. But we can and should plan for C++20. Cheers, Lars ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
> On 21 Jul 2020, at 22:51, Ville Voutilainen > wrote: > > On Tue, 21 Jul 2020 at 23:48, Ville Voutilainen > wrote: >> >> On Tue, 21 Jul 2020 at 22:12, Thiago Macieira >> wrote: >>> >>> On Tuesday, 21 July 2020 10:40:27 PDT Ville Voutilainen wrote: A very significant goal of this exercise is achieving notational convenience. Theoretical concerns about UB in the presence of papers that apparently excise that UB shouldn't stand in the way of that goal. >>> >>> Sorry, I don't agree. We can't use something that is unimplementable. >> >> Oh, when did that change? Was qobject_cast changed not to be UB? > > See also all the memcpys that are done with types that are > polymorphic, and the ones > where we memcpy types that have user-provided copy operations. qtbase > is UB left right > and center, but it's certainly interesting that when a new thing in it > might be clarified > not to be UB after all, we perform all kinds of somersaults to avoid > such dark corners. +1. Movable types are UB, still we do not want to sacrifice those, as they give a huge performance benefit, esp. for. Refcounted shared types. We now have something where we aim for API equivalence between an API we can offer our users and the additional jumps we have to do to achieve the same thing while hiding our data (purely because we want to offer BC). API equivalence is extremely important if we want this to work. The current implementation has a bit of UB in it that does work on all current compilers. It’s not inline in user code, so if a new compiler comes up that requires fixing this using e.g. inline assembly we can still do this (as taking the new compiler into use requires a recompile anyway). So I don’t really see where we have a huge problem with the current design that is not solvable without sacrificing it. Cheers, Lars ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
> On 2020 Jul 16, at 11:19, Ulf Hermann wrote: > > Data bindings are a cornerstone of most modern UI frameworks, and Qt is > actually late to the game. If we want Qt to stay relevant, then it needs to > offer the same kind of convenience and performance that other frameworks > offer. This would be an argument for converting all existing properties, and > paying the price, just to make the binding API available. Has someone done a survey of how bindings are implemented in other frameworks? Maybe there is a cool trick out there that we are missing, which would enable a big leap in efficiency. Do you have links to docs for the ones that you think look elegant? ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Tuesday, 21 July 2020 16:13:52 PDT Thiago Macieira wrote: > The memcpys qualify under all of those conditions, with even explicit > workarounds in the compilers. I don't see why you think qobject_cast has UB; > did you mean qFindChildren? I also want to make a distinction based on the potential danger. UB inside the library, where we control the conditions of build and can apply compiler-flag workarounds have limited damage. We can patch it with proper code if we find out we had broken code. UB where there's a different, albeit possibly slower, implementation in case we were wrong have limited damage. In this particular case, however, we have: a) code that is present in user's applications (generated by moc) b) compiler under the user's compiler settings c) with limited ability to apply workarounds for This is a very large damage if conditions change. It's very different to detect we've had UB all along from jumping with both feet into a new one. At least we have found a possible workaround, which is to write the subtraction in assembly, thereby hiding from the compiler and denying it any ability to optimise things incorrectly. (which is kind of dumb, because we don't want the code to add and subtract the same quantity, wasting two cycles; see https://godbolt.org/z/PvK987). I'm just trying to find out if there's a better way so we don't have to throw this design out. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel DPG Cloud Engineering ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Tuesday, 21 July 2020 14:18:15 PDT Volker Hilsheimer wrote: > auto text = qAction->text; > text.left(10); // booh Just make the internal property helper type neither copyable nor movable. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel DPG Cloud Engineering ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Tuesday, 21 July 2020 13:51:11 PDT Ville Voutilainen wrote: > See also all the memcpys that are done with types that are > polymorphic, and the ones > where we memcpy types that have user-provided copy operations. qtbase > is UB left right > and center, but it's certainly interesting that when a new thing in it > might be clarified > not to be UB after all, we perform all kinds of somersaults to avoid > such dark corners. I'm willing to accept _de jure_ UB today if there's a strong sentiment that this is an artifact of the way the standard is written, not an intentional carve-out like signed integer overflows are; preferably, with the committee on the record saying it wants to eventually fix this. A paper like P1839 being seriously considered counts as "being on the record" for me. With this stated direction, we can rely that compilers do not and will not optimise this UB away and will instead interpret it either as IB or as completely defined. Also required: that neither UBSan nor ASan produce errors when Qt or the user code is compiled with them. Using __attribute__ to silence them is acceptable. The memcpys qualify under all of those conditions, with even explicit workarounds in the compilers. I don't see why you think qobject_cast has UB; did you mean qFindChildren? -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel DPG Cloud Engineering ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Wed, 22 Jul 2020 at 00:18, Volker Hilsheimer wrote: > With the current design, notational convenience doesn’t work either: > > auto text = qAction->text; > text.left(10); // booh > > ‘text’ is not a QString, but a QAction::_qt_property_api_text object, with > broken... everythings. > > > And if people can’t use auto, then you can’t use standard ranged-for to > iterate over container type properties without spelling everyhing out. That’s > ... not convenient, I suppose. And that problem persists, even if we expose a > e.g QProperty reference through a public property member. Couldn't we add operator-> and begin/end to the property type? > The current implementation also adds, in case of us not being able to use > no_unique_address, a byte or even a pointer to each class in a class > hierarchy, bloating classes down in the inheritance tree. Plus the BC > challenge that might come with in the long run. > So, this is not only a problem of UB. There is well defined behavior that > seems to get in the way. Ack. ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
> On 21 Jul 2020, at 22:51, Ville Voutilainen > wrote: > > On Tue, 21 Jul 2020 at 23:48, Ville Voutilainen > wrote: >> >> On Tue, 21 Jul 2020 at 22:12, Thiago Macieira >> wrote: >>> >>> On Tuesday, 21 July 2020 10:40:27 PDT Ville Voutilainen wrote: A very significant goal of this exercise is achieving notational convenience. Theoretical concerns about UB in the presence of papers that apparently excise that UB shouldn't stand in the way of that goal. >>> >>> Sorry, I don't agree. We can't use something that is unimplementable. >> >> Oh, when did that change? Was qobject_cast changed not to be UB? > > See also all the memcpys that are done with types that are > polymorphic, and the ones > where we memcpy types that have user-provided copy operations. qtbase > is UB left right > and center, but it's certainly interesting that when a new thing in it > might be clarified > not to be UB after all, we perform all kinds of somersaults to avoid > such dark corners. With the current design, notational convenience doesn’t work either: auto text = qAction->text; text.left(10); // booh ‘text’ is not a QString, but a QAction::_qt_property_api_text object, with broken... everythings. And if people can’t use auto, then you can’t use standard ranged-for to iterate over container type properties without spelling everyhing out. That’s ... not convenient, I suppose. And that problem persists, even if we expose a e.g QProperty reference through a public property member. The current implementation also adds, in case of us not being able to use no_unique_address, a byte or even a pointer to each class in a class hierarchy, bloating classes down in the inheritance tree. Plus the BC challenge that might come with in the long run. So, this is not only a problem of UB. There is well defined behavior that seems to get in the way. Volker ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Tue, 21 Jul 2020 at 23:48, Ville Voutilainen wrote: > > On Tue, 21 Jul 2020 at 22:12, Thiago Macieira > wrote: > > > > On Tuesday, 21 July 2020 10:40:27 PDT Ville Voutilainen wrote: > > > A very significant goal of this exercise is achieving notational > > > convenience. Theoretical concerns about UB > > > in the presence of papers that apparently excise that UB shouldn't > > > stand in the way of that goal. > > > > Sorry, I don't agree. We can't use something that is unimplementable. > > Oh, when did that change? Was qobject_cast changed not to be UB? See also all the memcpys that are done with types that are polymorphic, and the ones where we memcpy types that have user-provided copy operations. qtbase is UB left right and center, but it's certainly interesting that when a new thing in it might be clarified not to be UB after all, we perform all kinds of somersaults to avoid such dark corners. ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Tue, 21 Jul 2020 at 22:12, Thiago Macieira wrote: > > On Tuesday, 21 July 2020 10:40:27 PDT Ville Voutilainen wrote: > > A very significant goal of this exercise is achieving notational > > convenience. Theoretical concerns about UB > > in the presence of papers that apparently excise that UB shouldn't > > stand in the way of that goal. > > Sorry, I don't agree. We can't use something that is unimplementable. Oh, when did that change? Was qobject_cast changed not to be UB? ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Tuesday, 21 July 2020 10:40:27 PDT Ville Voutilainen wrote: > A very significant goal of this exercise is achieving notational > convenience. Theoretical concerns about UB > in the presence of papers that apparently excise that UB shouldn't > stand in the way of that goal. Sorry, I don't agree. We can't use something that is unimplementable. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel DPG Cloud Engineering ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Tue, 21 Jul 2020 at 16:19, Volker Hilsheimer wrote: > object->property = newValue; > > > is not possible with this, but having to write > > object->setProperty(newValue); > > like we do today can’t be a blocker for the entire concept of bindable and > lazily evaluted properties. A very significant goal of this exercise is achieving notational convenience. Theoretical concerns about UB in the presence of papers that apparently excise that UB shouldn't stand in the way of that goal. ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
> On 21 Jul 2020, at 16:27, Fabian Kosmale wrote: > > Sacrificing operator= to avoid UB and hacks is probably fine (though I expect > some grumbling about the API). But would you suggest that "real" > (non-pimpled) QProperties and "fake" (pimpled) properties have a different > API? Using object->setValue(); works no matter how the property is implemented, and whether the QProperty is a public member of the public class, or a private member, or a pimpl’ed member. If the design goal was to have property access work the same way no matter how the data member storing the value relates to the public class, then yes, my proposal sacrifices that. Once we have C++ 20 (or 23 or whatever might have what we need), we can bring a uniform access API design back. Until then, the more important problems to solve seem to be binding and lazy evaluation. > And would you change the the property design to always go through the setter > when a binding becomes dirty? I suppose nothing has to change in that respect from what we have right now. If the macro IMPL takes a setter name as well, then it can expand to declare and implement it, forwarding to the generic setValue template. Ditto for getter. If that removes the assumption that a custom setter/getter would be called for updates from bindings, then that’s a good reason not to want to allow custom setters and getters. Wiring up the change and guard callbacks would be done the same as today as well. Volker > Am 21.07.20 um 15:16 schrieb Volker Hilsheimer: >> Taking a step back. >> >> I wonder if we can avoid this problem if we require people to write a bit >> more code. The idea to operate on the property directly looks nice at first >> sight, ie >> >> auto oldValue = object->enabled; >> object->enabled = newValue; >> >> but that seems to be the only reason why we need the maybe-zero-sized >> members in public classes, and the pointer-arithmetic to get to “this"; I’m >> not convinced that it's worth it. >> >> Realistically [1] we will have a lot of classes that would be a mix of old >> and new properties. Especially with that in mind, we do need to make sure >> that we have API consistency. For example, the property getters for boolean >> properties have always been called isProperty; never just “property". The >> new system departs from this. Making it cleverly generate an isProperty >> getter is just more magic. >> >> Requiring the implementing getter/setter methods explicitly, just today, is >> fine, I think. We might get something better later, but time is ticking and >> this shouldn’t stop the show. >> >> To set up bindings, one needs to do something like this with the current >> desitn (I might miss some variants): >> >> sink->otherProperty.setBinding(source->property); >> sink->otherProperty = Qt::makePropertyBinding(source->property); >> sink->otherProperty = Qt::makeBinding([&](){ return source->property; }); >> >> If instead we need to make a call on the source object, then it would remove >> the entire “this” pointer problem. To make the call unique for each >> property, we just have to declare a type for each property, which is easy. >> >> sink->otherProperty = source->makeBinding(); >> >> >> I’ve hacked a quick poc up at >> >> https://codereview.qt-project.org/c/qt/qtbase/+/308308 >> >> This is obviously not taking a lot of use cases into account, so I might be >> missing a lot, but the concept should be fairly extensible, for intance for >> subscribe, setValue, value methods. The only downside I see is that >> >> object->property = newValue; >> >> >> is not possible with this, but having to write >> >> object->setProperty(newValue); >> >> like we do today can’t be a blocker for the entire concept of bindable and >> lazily evaluted properties. >> >> >> Volker >> >> >> [1] There might be many classes that we can’t port entirely over to the new >> property system, at least not without subtle changes to behavior that we >> can’t accept. Qt’s properties are not designed to be orthogonal; changing >> them frequently has side effects on other properties; getters sometimes >> apply some additional logic for defaults and overrides; we have virtual >> setters, etc. This has turned out to be quite complex over the last 10 days >> of trying, and the resulting code has not always been a step into the >> direction of maintainability. >> >> ___ >> Development mailing list >> Development@qt-project.org >> https://lists.qt-project.org/listinfo/development > > -- > -- > Fabian Kosmale > Software Engineer > > The Qt Company GmbH > Erich-Thilo-Str. 10 > D-12489 Berlin > fabian.kosm...@qt.io > http://qt.io > > Geschäftsführer: Mika Pälsi, > Juha Varelius, Mika Harjuaho > Sitz der Gesellschaft: Berlin, > Registergericht: Amtsgericht > Charlottenburg, HRB 144331 B > -- ___ Development mailing list Development@qt-pr
Re: [Development] QProperty and library coding guide
On Tuesday, 21 July 2020 07:27:11 PDT Fabian Kosmale wrote: > Sacrificing operator= to avoid UB and hacks is probably fine (though I > expect some grumbling about the API). But would you suggest that > "real" (non-pimpled) QProperties and "fake" (pimpled) properties have a > different API? It doesn't have to. The non-pimpled ones can also "hide" behiind an inline function. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel DPG Cloud Engineering ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
Sacrificing operator= to avoid UB and hacks is probably fine (though I expect some grumbling about the API). But would you suggest that "real" (non-pimpled) QProperties and "fake" (pimpled) properties have a different API? And would you change the the property design to always go through the setter when a binding becomes dirty? Am 21.07.20 um 15:16 schrieb Volker Hilsheimer: Taking a step back. I wonder if we can avoid this problem if we require people to write a bit more code. The idea to operate on the property directly looks nice at first sight, ie auto oldValue = object->enabled; object->enabled = newValue; but that seems to be the only reason why we need the maybe-zero-sized members in public classes, and the pointer-arithmetic to get to “this"; I’m not convinced that it's worth it. Realistically [1] we will have a lot of classes that would be a mix of old and new properties. Especially with that in mind, we do need to make sure that we have API consistency. For example, the property getters for boolean properties have always been called isProperty; never just “property". The new system departs from this. Making it cleverly generate an isProperty getter is just more magic. Requiring the implementing getter/setter methods explicitly, just today, is fine, I think. We might get something better later, but time is ticking and this shouldn’t stop the show. To set up bindings, one needs to do something like this with the current desitn (I might miss some variants): sink->otherProperty.setBinding(source->property); sink->otherProperty = Qt::makePropertyBinding(source->property); sink->otherProperty = Qt::makeBinding([&](){ return source->property; }); If instead we need to make a call on the source object, then it would remove the entire “this” pointer problem. To make the call unique for each property, we just have to declare a type for each property, which is easy. sink->otherProperty = source->makeBinding(); I’ve hacked a quick poc up at https://codereview.qt-project.org/c/qt/qtbase/+/308308 This is obviously not taking a lot of use cases into account, so I might be missing a lot, but the concept should be fairly extensible, for intance for subscribe, setValue, value methods. The only downside I see is that object->property = newValue; is not possible with this, but having to write object->setProperty(newValue); like we do today can’t be a blocker for the entire concept of bindable and lazily evaluted properties. Volker [1] There might be many classes that we can’t port entirely over to the new property system, at least not without subtle changes to behavior that we can’t accept. Qt’s properties are not designed to be orthogonal; changing them frequently has side effects on other properties; getters sometimes apply some additional logic for defaults and overrides; we have virtual setters, etc. This has turned out to be quite complex over the last 10 days of trying, and the resulting code has not always been a step into the direction of maintainability. ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development -- -- Fabian Kosmale Software Engineer The Qt Company GmbH Erich-Thilo-Str. 10 D-12489 Berlin fabian.kosm...@qt.io http://qt.io Geschäftsführer: Mika Pälsi, Juha Varelius, Mika Harjuaho Sitz der Gesellschaft: Berlin, Registergericht: Amtsgericht Charlottenburg, HRB 144331 B -- ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
> On 20 Jul 2020, at 20:30, Thiago Macieira wrote: > > On Monday, 20 July 2020 08:40:06 PDT Oswald Buddenhagen wrote: >> anyway, this can be trivially bypassed by just using an arbitrary >> address and subtracting the offset. or using offsetof, indeed. in any >> case it's 3 minutes of work. > > Sorry, an arbitrary address won't work either because it's still a > dereference. > > Suppose: > >const auto dummy = static_cast(0x4000); >const auto member = &dummy->member; >qptrdiff offset = quintptr(member) - quintptr(dummy) >return static_cast(quintptr(this) - offset); > > The problem is that the first line is creating a pointer to a memory location > that does not have a valid Object object. So when the second line does > dummy->member > this expression is UB. It doesn't matter that the compiler usually implements > the full expression &dummy->member as arithmetic on the pointers without > dereferencing them; from the language's point of view, a dereference did > happen and therefore it's UB. This is no different than: > Object *ptr = nullptr; > ptr->staticFunction(); > See commit 88cf9402e336fddeb673c92f3c14da47a9f8450b[1]. > > Also note how both ASan and UBSan are likely to complain. Whatever our > implementation is, it must pass both sanitisers. > > [1] https://code.qt.io/cgit/qt/qtbase.git/commit/? > id=88cf9402e336fddeb673c92f3c14da47a9f8450b > -- > Thiago Macieira - thiago.macieira (AT) intel.com > Software Architect - Intel DPG Cloud Engineering Taking a step back. I wonder if we can avoid this problem if we require people to write a bit more code. The idea to operate on the property directly looks nice at first sight, ie auto oldValue = object->enabled; object->enabled = newValue; but that seems to be the only reason why we need the maybe-zero-sized members in public classes, and the pointer-arithmetic to get to “this"; I’m not convinced that it's worth it. Realistically [1] we will have a lot of classes that would be a mix of old and new properties. Especially with that in mind, we do need to make sure that we have API consistency. For example, the property getters for boolean properties have always been called isProperty; never just “property". The new system departs from this. Making it cleverly generate an isProperty getter is just more magic. Requiring the implementing getter/setter methods explicitly, just today, is fine, I think. We might get something better later, but time is ticking and this shouldn’t stop the show. To set up bindings, one needs to do something like this with the current desitn (I might miss some variants): sink->otherProperty.setBinding(source->property); sink->otherProperty = Qt::makePropertyBinding(source->property); sink->otherProperty = Qt::makeBinding([&](){ return source->property; }); If instead we need to make a call on the source object, then it would remove the entire “this” pointer problem. To make the call unique for each property, we just have to declare a type for each property, which is easy. sink->otherProperty = source->makeBinding(); I’ve hacked a quick poc up at https://codereview.qt-project.org/c/qt/qtbase/+/308308 This is obviously not taking a lot of use cases into account, so I might be missing a lot, but the concept should be fairly extensible, for intance for subscribe, setValue, value methods. The only downside I see is that object->property = newValue; is not possible with this, but having to write object->setProperty(newValue); like we do today can’t be a blocker for the entire concept of bindable and lazily evaluted properties. Volker [1] There might be many classes that we can’t port entirely over to the new property system, at least not without subtle changes to behavior that we can’t accept. Qt’s properties are not designed to be orthogonal; changing them frequently has side effects on other properties; getters sometimes apply some additional logic for defaults and overrides; we have virtual setters, etc. This has turned out to be quite complex over the last 10 days of trying, and the resulting code has not always been a step into the direction of maintainability. ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Monday, 20 July 2020 08:40:06 PDT Oswald Buddenhagen wrote: > anyway, this can be trivially bypassed by just using an arbitrary > address and subtracting the offset. or using offsetof, indeed. in any > case it's 3 minutes of work. Sorry, an arbitrary address won't work either because it's still a dereference. Suppose: const auto dummy = static_cast(0x4000); const auto member = &dummy->member; qptrdiff offset = quintptr(member) - quintptr(dummy) return static_cast(quintptr(this) - offset); The problem is that the first line is creating a pointer to a memory location that does not have a valid Object object. So when the second line does dummy->member this expression is UB. It doesn't matter that the compiler usually implements the full expression &dummy->member as arithmetic on the pointers without dereferencing them; from the language's point of view, a dereference did happen and therefore it's UB. This is no different than: Object *ptr = nullptr; ptr->staticFunction(); See commit 88cf9402e336fddeb673c92f3c14da47a9f8450b[1]. Also note how both ASan and UBSan are likely to complain. Whatever our implementation is, it must pass both sanitisers. [1] https://code.qt.io/cgit/qt/qtbase.git/commit/? id=88cf9402e336fddeb673c92f3c14da47a9f8450b -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel DPG Cloud Engineering ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Monday, 20 July 2020 11:06:36 PDT Giuseppe D'Angelo via Development wrote: > Il 20/07/20 07:21, Thiago Macieira ha scritto: > > ASM is not a solution. There's at least one major compiler (MSVC) that > > doesn't allow any assembler. > > What do you mean, MSVC doesn't allow inline ASM? Correct. To be clear: MSVC 64-bit doesn't allow inline assembler. The 32-bit versiondoes. > I'm not proposing that the ASM itself needs to be emitted by moc, moc > could just call a function implemented (in ASM) somewhere in > qobjectdefs.h or so... With MSVC, it needs to be defined in an .asm file. So it's going to be out-of- line every time. > > But see Ville's email. I think the pointer arithmetic is actually fine. > > Would be fine too with uchar*. > > I'm really not sure what part of that paper would make it fine? If you have a valid object, the paper does allow pointer arithmetic to access the object's representation. This is the direction the committee wants to go and it something compilers already do, so we can probably rely on the current behaviour remaining. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel DPG Cloud Engineering ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
Il 20/07/20 07:21, Thiago Macieira ha scritto: ASM is not a solution. There's at least one major compiler (MSVC) that doesn't allow any assembler. What do you mean, MSVC doesn't allow inline ASM? I'm not proposing that the ASM itself needs to be emitted by moc, moc could just call a function implemented (in ASM) somewhere in qobjectdefs.h or so... But see Ville's email. I think the pointer arithmetic is actually fine. Would be fine too with uchar*. I'm really not sure what part of that paper would make it fine? -- Giuseppe D'Angelo | giuseppe.dang...@kdab.com | Senior Software Engineer KDAB (France) S.A.S., a KDAB Group company Tel. France +33 (0)4 90 84 08 53, http://www.kdab.com KDAB - The Qt, C++ and OpenGL Experts smime.p7s Description: Firma crittografica S/MIME ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Monday, 20 July 2020 10:26:34 PDT Ville Voutilainen wrote: > The only dispute in the offsetof article is about whether that > indirection is UB in C. In C++ it is, and will remain so. > That's why C++-compliant stddef.h implementations don't do that. $ gcc -dM -E -include stddef.h -xc++ /dev/null | grep offsetof #define offsetof(TYPE,MEMBER) __builtin_offsetof (TYPE, MEMBER) https://gcc.godbolt.org/z/jzY1qe (if the MSVC isn't showing, scroll to the bottom) -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel DPG Cloud Engineering ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Mon, 20 Jul 2020 at 19:09, Thiago Macieira wrote: > > On Monday, 20 July 2020 08:40:06 PDT Oswald Buddenhagen wrote: > > On Mon, Jul 20, 2020 at 07:32:41AM -0700, Thiago Macieira wrote: > > >I am not going to accept a null-pointer dereference in there. The > > >static_cast(nullptr)-> must go. > > > > this this construct is actually UB is disputed on wikipedia (in the > > offsetof article). > > There's no dispute. It's a null-pointer dereference, so it's UB. The member-access will not become valid. The only minor dispute is in http://open-std.org/JTC1/SC22/WG21/docs/cwg_active.html#232 but that will not make indirecting through a null pointer like that valid. The only dispute in the offsetof article is about whether that indirection is UB in C. In C++ it is, and will remain so. That's why C++-compliant stddef.h implementations don't do that. ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Monday, 20 July 2020 08:40:06 PDT Oswald Buddenhagen wrote: > On Mon, Jul 20, 2020 at 07:32:41AM -0700, Thiago Macieira wrote: > >I am not going to accept a null-pointer dereference in there. The > >static_cast(nullptr)-> must go. > > this this construct is actually UB is disputed on wikipedia (in the > offsetof article). There's no dispute. It's a null-pointer dereference, so it's UB. Whether offsetof() uses that technique to provide a defined behaviour or not is irrelevant. offsetof() is a macro provided by the compiler, so the compiler maintainers know what code their compiler will generate. > anyway, this can be trivially bypassed by just using an arbitrary > address and subtracting the offset. or using offsetof, indeed. in any > case it's 3 minutes of work. ;) Someone please submit it then. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel DPG Cloud Engineering ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Mon, Jul 20, 2020 at 07:32:41AM -0700, Thiago Macieira wrote: I am not going to accept a null-pointer dereference in there. The static_cast(nullptr)-> must go. this this construct is actually UB is disputed on wikipedia (in the offsetof article). anyway, this can be trivially bypassed by just using an arbitrary address and subtracting the offset. or using offsetof, indeed. in any case it's 3 minutes of work. ;) ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Monday, 20 July 2020 01:23:39 PDT Lars Knoll wrote: > But I don’t see why we would need to do this now, if the code we have works > fine on current compilers. It’s all non inline, so we could add those kind > of workarounds only if they become a requirement for a certain compiler. It's "inline" in the sense that it's generated by moc and therefore ends up in user code. That severely limits our ability to react, since users may (for their own reasons) want to restrict to a specific Qt version. I am not going to accept a null-pointer dereference in there. The static_cast(nullptr)-> must go. > > > > But see Ville's email. I think the pointer arithmetic is actually fine. > > Would be fine too with uchar*. > > What we’re doing is basically the reverse operation of: > > T* o = ...; > U *m = &o->m; > > We need to go from the pointer to m back to the pointer of the surrounding > object. While one way it perfectly defined by C++, there is unfortunately > no way to reverse the operation in the standard. Time to write a paper for the C++ committee. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel System Software Products ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
> From: Development on behalf of Ulf > Hermann >>> However, for Q_GADGET this would fall apart. > > Actually, with a Q_GADGET you usually don't have a private object. > That's the whole point of it. Then you don't need property wrappers, either. Just for clarification: actually you usually do have a private object (at least in Qt classes) in gadgets. Examples: QPainter QFont QTextFormat QKeySequence QPalette QDBusConnection and I think that more Qt's gadgets have a private object than those that don't. Jarek ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
> On 20 Jul 2020, at 07:24, Thiago Macieira wrote: > > On Sunday, 19 July 2020 14:42:24 PDT Giuseppe D'Angelo via Development wrote: >> * change /*2*/ to use ASM. We know the ABI of the platforms we support >> and we know how to calculate the correct pointer value, we just need to >> stop C/C++ from reason about it and flagging it as possible UB. Yes, >> it's a crude hack... > > ASM is not a solution. There's at least one major compiler (MSVC) that > doesn't > allow any assembler. Sure it does, just not inline. So ASM can be a solution if required. For MSVC, we’d simply call the assembly out of line. But I don’t see why we would need to do this now, if the code we have works fine on current compilers. It’s all non inline, so we could add those kind of workarounds only if they become a requirement for a certain compiler. > > But see Ville's email. I think the pointer arithmetic is actually fine. Would > be fine too with uchar*. What we’re doing is basically the reverse operation of: T* o = ...; U *m = &o->m; We need to go from the pointer to m back to the pointer of the surrounding object. While one way it perfectly defined by C++, there is unfortunately no way to reverse the operation in the standard. Cheers, Lars > > -- > Thiago Macieira - thiago.macieira (AT) intel.com > Software Architect - Intel System Software Products > > > > ___ > Development mailing list > Development@qt-project.org > https://lists.qt-project.org/listinfo/development ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Sunday, 19 July 2020 14:42:24 PDT Giuseppe D'Angelo via Development wrote: > * change /*2*/ to use ASM. We know the ABI of the platforms we support > and we know how to calculate the correct pointer value, we just need to > stop C/C++ from reason about it and flagging it as possible UB. Yes, > it's a crude hack... ASM is not a solution. There's at least one major compiler (MSVC) that doesn't allow any assembler. But see Ville's email. I think the pointer arithmetic is actually fine. Would be fine too with uchar*. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel System Software Products ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On 16-07-2020 13:08, Edward Welbourne wrote: Il 16/07/20 12:43, Volker Hilsheimer ha scritto: For pre-C++20 (where it’s possible to have zero-size structs), and for compilers that don’t respect the [[no_unqiue_address]] attribute, all these struct-instances are put into a union. In that case, a class using QProperty will be larger (by the same amount no matter the number of properties) than the same class in Qt 5. With C+++ 20 and compilers that do respect [[no_unique_address]], the size and layout of these classes will be the same. Giuseppe D'Angelo (16 July 2020 12:58) requested: Could anyone please illustrate with some code snippets how to achieve this, in practice, in a number of use cases? E.g. client code (non pimpled QObject subclass), (Qt) library code (pimpled QObject subclass), etc.; gadgets (does QProperty work there?); with and without other Q_PROPERTY/QProperty already present, etc. As noted in my last mail, documentation is still lagging. Several of us - previously ignorant of the new system - are currently helping Ulf and Fabian with conversion. We are, in the process, helping to debug the draft instructions for how to convert and point out gaps in the system that make this harder than it should be. Hopefully, once we've spent a week or two hassling Ulf and Fabian with questions, they'll have the right things in place and know how to document it clearly. However, doing so today would soak up some of their time that is better spent getting the system into the right state so that the documentation doesn't need repeated updates ... Please be patient, we are working on this, Please understand that waiting with this will also make other contributors who will need to deal with QProperty wait, including those who will need to OK such changes (such as Thiago). So, you are making dozens of people wait to protect the time of two people? That doesn't make much sense IMO. All that was asked for were some examples, not fully fledged detailed documentation. Cheers, André Eddy. ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
Il 19/07/20 20:42, Thiago Macieira ha scritto: In that sense, Peppe's suggestion of C++17 offsetof is better. To clarify, I was proposing to do something like this: Type Klass::_qt_property_api_propertyName::value() const { /*1*/ const size_t propertyMemberOffset = reinterpret_cast(&(static_cast(nullptr)->propertyName)); /*2*/ const auto *thisPtr = reinterpret_cast(reinterpret_cast(this) - propertyMemberOffset); return thisPtr->d_func()->property.value(); } * change /*1*/ become offsetof(Klass, propertyName); * change /*2*/ to use ASM. We know the ABI of the platforms we support and we know how to calculate the correct pointer value, we just need to stop C/C++ from reason about it and flagging it as possible UB. Yes, it's a crude hack... :( My 2 c, -- Giuseppe D'Angelo | giuseppe.dang...@kdab.com | Senior Software Engineer KDAB (France) S.A.S., a KDAB Group company Tel. France +33 (0)4 90 84 08 53, http://www.kdab.com KDAB - The Qt, C++ and OpenGL Experts smime.p7s Description: Firma crittografica S/MIME ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Sun, 19 Jul 2020 at 21:52, Thiago Macieira wrote: > > On Sunday, 19 July 2020 08:20:01 PDT Thiago Macieira wrote: > > 1. Revert the feature. > > 2. Write papers to add necessary functionality to C++23, like reversing a > >pointer-to-member-object back to the containing object > > 3. Require C++23 in Qt 7.0 > > > > double Square::_qt_property_api_width::value() const > > { > > return retrieveContainer<&Square::width>(this)->d->width; > > } > > I've dug up my old idea of pointer-to-container. This can be implemented as a > standard library feature, without a core language change. > > Here's a test implementation modernised with C++17 NTTPs: > https://gcc.godbolt.org/z/GGGE1c > I *believe* it has no UB but does rely on implementation-defined behaviour of > a PMO. This IB works for QObject because we don't allow virtual inheritance > and also because by construction the type is only done on the class that > introduced the member. A generic solution of PMO reversal requires more work. > > In that sense, Peppe's suggestion of C++17 offsetof is better. > > The important detail is here: > static Klass *memberToContainer(Type pmo, ConstMemberType *member) > { > quintptr memberAddress = quintptr(member); > typename QIntegerForSizeof::Signed offset; > memcpy(&offset, &pmo, sizeof(offset)); > quintptr containerAddress = memberAddress - offset; > return reinterpret_cast(containerAddress); > } > > The memcpy is IB. The containerAddress calculation is the same as in the code > currently generated by moc, which I initially claimed to be UB, but now I'm > not sure. Is there something in it that's UB besides what http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2019/p1839r2.pdf clarifies to become well-defined? ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Sunday, 19 July 2020 08:20:01 PDT Thiago Macieira wrote: > 1. Revert the feature. > 2. Write papers to add necessary functionality to C++23, like reversing a >pointer-to-member-object back to the containing object > 3. Require C++23 in Qt 7.0 > > double Square::_qt_property_api_width::value() const > { > return retrieveContainer<&Square::width>(this)->d->width; > } I've dug up my old idea of pointer-to-container. This can be implemented as a standard library feature, without a core language change. Here's a test implementation modernised with C++17 NTTPs: https://gcc.godbolt.org/z/GGGE1c I *believe* it has no UB but does rely on implementation-defined behaviour of a PMO. This IB works for QObject because we don't allow virtual inheritance and also because by construction the type is only done on the class that introduced the member. A generic solution of PMO reversal requires more work. In that sense, Peppe's suggestion of C++17 offsetof is better. The important detail is here: static Klass *memberToContainer(Type pmo, ConstMemberType *member) { quintptr memberAddress = quintptr(member); typename QIntegerForSizeof::Signed offset; memcpy(&offset, &pmo, sizeof(offset)); quintptr containerAddress = memberAddress - offset; return reinterpret_cast(containerAddress); } The memcpy is IB. The containerAddress calculation is the same as in the code currently generated by moc, which I initially claimed to be UB, but now I'm not sure. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel System Software Products ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Sunday, 19 July 2020 03:51:00 PDT Oswald Buddenhagen wrote: > - the compiler becomes intentionally belligerent, in which case an >override switch will be provided as well (if not instantly, then after >the outcry that immediately follows) Even if that were the case, we'd need EVERYONE's code to use this switch. Not just when Qt is being built, where we control the options. We'd need all our users to use it, in their buildsystems, whichever they may be. That's why this is not acceptable. > If Peppe's idea doesn't work, then: 1. Revert the feature. 2. Write papers to add necessary functionality to C++23, like reversing a pointer-to-member-object back to the containing object 3. Require C++23 in Qt 7.0 double Square::_qt_property_api_width::value() const { return retrieveContainer<&Square::width>(this)->d->width; } -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel System Software Products ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Sun, 19 Jul 2020 at 15:25, Oswald Buddenhagen wrote: > (side effects of) actual optimizations are by definition not intentional > belligerence. (one would, however, expect that entire chunks of code > being thrown away would result in a warning that informs about > specifically that (and not just the underlying warning, which may or may > not be enabled).) One could hope so, but expecting that would be foolish. Current optimizers seem to consider warnings to be a job of the front-end, but if the optimizations are value-based rather than symbolic, the front-end can't warn, and then the optimizer won't, and dead code that was considered dead because it has UB will just be axed without warning. ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Sun, Jul 19, 2020 at 01:14:08PM +0200, Giuseppe D'Angelo via Development wrote: offsetof is conditionally-supported for non standard layout classes in C++17.: oh, good. that means that the second line should also keep working, as that is semantically equivalent with offsetof being meaningful, afaict. On Sun, Jul 19, 2020 at 01:20:12PM +0200, Giuseppe D'Angelo via Development wrote: Il 19/07/20 12:51, Oswald Buddenhagen ha scritto: - the compiler becomes intentionally belligerent, in which case an override switch will be provided as well (if not instantly, then after the outcry that immediately follows) File under "surely no compiler will optimize away X!", for X in [...] (side effects of) actual optimizations are by definition not intentional belligerence. (one would, however, expect that entire chunks of code being thrown away would result in a warning that informs about specifically that (and not just the underlying warning, which may or may not be enabled).) ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
Il 19/07/20 12:51, Oswald Buddenhagen ha scritto: - the compiler becomes intentionally belligerent, in which case an override switch will be provided as well (if not instantly, then after the outcry that immediately follows) File under "surely no compiler will optimize away X!", for X in * unspecified pointer comparisons * signed integer over/underflows * data races (on bitfields) * volatile in lieu of proper atomic access * proving that a loop doesn't terminate, hence the loop is never entered, and applying dead code optimization to it * ... To do any of the above is not belligerent, AND you have no way to switch the above optimizations off. (Also, you don't want to.) In other words: this is playing with fire in the long term run, that's why I suggested to bypass the C++ abstract machine, rely on ABI and use ASM. My 2 c, -- Giuseppe D'Angelo | giuseppe.dang...@kdab.com | Senior Software Engineer KDAB (France) S.A.S., a KDAB Group company Tel. France +33 (0)4 90 84 08 53, http://www.kdab.com KDAB - The Qt, C++ and OpenGL Experts smime.p7s Description: Firma crittografica S/MIME ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
Il 19/07/20 12:51, Oswald Buddenhagen ha scritto: - the compiler somehow starts to actually make use of the freedom granted by the fact that QObject is not standard-layout (this, btw, is also the reason why peppe's suggestion to use offsetof doesn't fix UB). offsetof is conditionally-supported for non standard layout classes in C++17.: http://eel.is/c++draft/support.types.layout#1.sentence-2 I haven't found any note in GCC/Clang/MSVC docs saying that they won't support it in this case, hence it's supported. http://eel.is/c++draft/intro.compliance#:behavior,conditionally-supported My 2 c, -- Giuseppe D'Angelo | giuseppe.dang...@kdab.com | Senior Software Engineer KDAB (France) S.A.S., a KDAB Group company Tel. France +33 (0)4 90 84 08 53, http://www.kdab.com KDAB - The Qt, C++ and OpenGL Experts smime.p7s Description: Firma crittografica S/MIME ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Sat, Jul 18, 2020 at 10:10:41AM -0700, Thiago Macieira wrote: On Friday, 17 July 2020 23:32:41 PDT Simon Hausmann wrote: This hack has been in QtQml in production since its release in 2010 (see static cast selector). It would be a shame if this stopped working The problem here is the damage that can happen if a breakage happens. i can think of only two ways how this can stop working: - the compiler becomes intentionally belligerent, in which case an override switch will be provided as well (if not instantly, then after the outcry that immediately follows) - the compiler somehow starts to actually make use of the freedom granted by the fact that QObject is not standard-layout (this, btw, is also the reason why peppe's suggestion to use offsetof doesn't fix UB). however, this would also come with a massive BC break, in which case we'd have bigger problems anyway. so it's guaranteed that a compat switch would be provided as well, exactly because much code wants to stay BC. anyway, i consider this case entirely hypothetical, as there is no reason to break this when compiling for real hardware (or something that resembles it, like wasm, afaik); it might be different for some vms. So what's the [efficient] non-UB solution? ;-) ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Sat, 18 Jul 2020 at 03:58, Ulf Hermann wrote: > > > I must be missing something. I tend to think of eventloops with notify > > signals are an improvement over polling. You statement seems to say > > that asking for a value is better, and notifications are to be avoided? > > I'm not saying that you should go back to polling. In the case that you > have genuine events, for example input or network activity, signals may > just be the thing you need. This whole discussion is specifically about > properties and their _change_ signals. > > Mind that the propagation of dirty flags across a binding graph is a > kind of "change signal" in its own right. With QProperty, we just don't > calculate the values right away when we notice that a related property > has changed. Why is that? > > Properties can change fairly often, and synchronously triggering a chain > of calculations whenever some property changes can be inefficient and > can lead to unexpected intermediate values. This is why we introduce > lazy evaluation for property bindings. > > With this system, on some level, you indeed have to poll a property to > make something happen outside the system. However, certain technologies > are inherently based on polling. For example the scene graph rendering a > frame every 16ms will poll for changed items every time. For this, a > lazy evaluation strategy makes more sense than the usual change signals. > > If you want to take advantage of lazy evaluation in such places, you > should stop using the change signals there, though. Whenever a property > has a change signal, it and everything it depends on needs to be > evaluated eagerly. > > best, > Ulf Will language bindings be able to take advantage of the new QProperty system? For example, will it be possible to create a lazy-evaluated property binding from non-C++ code? (For reference, Qt for Python currently creates new properties this way: https://wiki.qt.io/Qt_for_Python_UsingQtProperties ) Regards, Sze-Howe ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
Il 18/07/20 12:08, Arno Rehn ha scritto: Can't we just hide the QProperty behind a method call, like with an ordinary getter method? E.g. class Foo { // ... QPropert &bar() { Q_D(Foo); return d->bar; } }; struct FooPrivate { QProperty bar; }; Sure, property access then isn't as nice as with the struct wrapper, because you have the method call in between, but at least it's not undefined behavior and there's a lot less complexity when putting it into the pimpl object. I'm assuming that one of the goals is to make the new property syntax invisible and identical for the users. Code like this auto value = obj->property(); must still compile, and decltype(value) better be the actual property type and not any proxy object (which are still second class citizens in C++). My 2 c, -- Giuseppe D'Angelo | giuseppe.dang...@kdab.com | Senior Software Engineer KDAB (France) S.A.S., a KDAB Group company Tel. France +33 (0)4 90 84 08 53, http://www.kdab.com KDAB - The Qt, C++ and OpenGL Experts smime.p7s Description: Firma crittografica S/MIME ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Friday, 17 July 2020 23:32:41 PDT Simon Hausmann wrote: > This hack has been in QtQml in production since its release in 2010 (see > static cast selector). > > It would be a shame if this stopped working The problem here is the damage that can happen if a breakage happens. If the QtQml code is happening behind the scenes and we can change it when an issue is detected, any damage is contained. We can also disable it when UBSan is active. I am perfectly willing to take UB where it's contained like that. I am not willing to take it when it is in everyone's code, like in macros or with moc-generated code. We need to be compatible with all compilers from 2019 to 2030, with 9 of those 11 years not yet come to pass. This needs to have a non-UB solution. The UB one can be a special optimisation, which we carefully enable where we know it works. So what's the non-UB solution? -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel System Software Products ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Saturday, 18 July 2020 07:11:51 PDT Giuseppe D'Angelo via Development wrote: > > auto prop = object->propertyName; > > return prop.value(); > > How? Just like QStringBuilder, there's no way to block a `const auto &`, > is there? A reference is ok. The problem is the copy or move, since now the object's this no longer points to the dummy member inside the QObject-derived class, but to somewhere on the stack. Then that UB pointer manipulation begins reading garbage and making matters go from bad to worse. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel System Software Products ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
Il 17/07/20 19:55, Thiago Macieira ha scritto: moc generates: Type Klass::_qt_property_api_propertyName::value() const { const size_t propertyMemberOffset = reinterpret_cast(&(static_cast(nullptr)->propertyName)); const auto *thisPtr = reinterpret_cast( reinterpret_cast(this) - propertyMemberOffset); return thisPtr->d_func()->property.value(); } The first two lines of this function are UB. It MUST be fixed. The first line smells like offsetof, which we might be lucky enough to use -- in C++17 it became conditionally supported whether it works on non-standard layout classes (QObject), and apparently GCC/Clang/MSVC all support it. The second line smells 99.99% unfixable UB. Would using ASM be an acceptable "fix"? In the process, please also fix this code: auto prop = object->propertyName; return prop.value(); How? Just like QStringBuilder, there's no way to block a `const auto &`, is there? Thanks, -- Giuseppe D'Angelo | giuseppe.dang...@kdab.com | Senior Software Engineer KDAB (France) S.A.S., a KDAB Group company Tel. France +33 (0)4 90 84 08 53, http://www.kdab.com KDAB - The Qt, C++ and OpenGL Experts smime.p7s Description: Firma crittografica S/MIME ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
Il 17/07/20 19:36, Thiago Macieira ha scritto: So in your example QSctpSocket would still be 24 bytes, because the inheritance is not deep enough to make sizeof 32? Yes, with the IA-64 ABI, assuming we don't mandate [[no_unique_address]] of course. Still, is it worth breaking ABI for sparing 8 bytes every 8 subclasses? With MSVC, it's 56 bytes. Well, this can't be helped anyhow as MSVC doesn't support [[no_unique_address]], so the implementation is going to be the union, with the associated costs. Thanks, -- Giuseppe D'Angelo | giuseppe.dang...@kdab.com | Senior Software Engineer KDAB (France) S.A.S., a KDAB Group company Tel. France +33 (0)4 90 84 08 53, http://www.kdab.com KDAB - The Qt, C++ and OpenGL Experts smime.p7s Description: Firma crittografica S/MIME ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On 17/07/2020 19:30, Ulf Hermann wrote: >> I am confused. Removing the struct means we’re back to a >> setFoo()/foo() style API, and especially, we have a different API for >> people using Property directly and what we provide in our public API. >> That simply doesn’t make sense. > > I was assuming we'd also add setBindingOnFoo() etc. Yes, that would be > different API than what we provide for QProperty directly. If we can > avoid it, we should. Can't we just hide the QProperty behind a method call, like with an ordinary getter method? E.g. class Foo { // ... QPropert &bar() { Q_D(Foo); return d->bar; } }; struct FooPrivate { QProperty bar; }; Sure, property access then isn't as nice as with the struct wrapper, because you have the method call in between, but at least it's not undefined behavior and there's a lot less complexity when putting it into the pimpl object. Regards, Arno -- Arno Rehn Tel +49 89 189 166 0 Fax +49 89 189 166 111 a.r...@menlosystems.com www.menlosystems.com Menlo Systems GmbH Am Klopferspitz 19a, 82152 Martinsried, Germany Amtsgericht München HRB 138145 Geschäftsführung: Dr. Michael Mei, Dr. Ronald Holzwarth USt.-IdNr. DE217772017, St.-Nr. 14316170324 ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
Am 17.07.20 um 21:35 schrieb Ulf Hermann: >> Mhh, it there are no change signals anymore, i guess i also can't use >> QObject::connect() anymore and rather use a binding instead ? This is >> fine, but if two objects are living in different threads how does it >> work then ? With a Queued connection how it works with signals/slots is >> pretty clear, but in which thread is the binding evaluated ? > > Binding properties from different threads is not supported. Bindings > should be lightweight. Usually they'd be used for closely related bits > of data. Those rarely live in different threads. Building thread > synchronization into bindings would make them more expensive for > little gain. > > You can, however, still use queued signals in this scenario. QProperty > has a subscribe() method, and if the change of a property is actually > something you want to communicate across thread boundaries, you can > attach a function that sends a signal to a QProperty via subscribe(). > There is also QNotifiedProperty. I would advise against all of this, > though. Sending the signal forces the property and everything it > depends on to be eagerly evaluated. There likely are other ways to > organize your thread synchronization. > ok, i guess we need a example for this then. Sure properties are not something you use across threads very often, but sometimes you still do and the old way works perfectly fine as you just connect the signals. If there is a way on how it can be done, even if this is not as convenient as connecting the signals, but has other benefits like the lazy evaluation, if this has a good documentation, then we are good. We just need to make sure to be better than the QML documentation in the first days, which was really horrible... >> With the old properties it's also possible to define a custom behavior >> for the setter and getter. E.g. for the getter to not emit the changed >> signal, but just call a worker thread to to this and wait for the >> feedback to do the actual change and emit the change signal. I guess all >> this is not possibly anymore with the new QProperty ? If we define that >> behavior like this can not be done with QProperty but the old way should >> be used instead everything is fine, but doesn't make the API >> inconsistent ? > > You get value guards with QNotifiedProperty, and soon also with > QProperty: https://codereview.qt-project.org/c/qt/qtbase/+/307894 > With those, you can introspect and/or modify a new value before it is > set. You can do the additional work in a value guard, and you can even > reject values that way. Using a value guard does not even force eager > evaluation. great, sounds exactly what i would need ;-) > >> As I understood it, we don't want to break SC too much so we will keep >> all setters/getters in our API. >> Let's say we create a new type derived from QQuickItem and use a >> QProperty there, let's name this property "foo". >> Doesn't it mean we now have a class, which has functions like setWidth >> and setHeight, but not a function for setFoo ? > > Q_PRIVATE_QPROPERTY generates a setter, setFoo in this case, that just > calls the setValue() function of the propery. If you add the property > directly in the public object, you can do the same manually. Nice! Dominik ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
Hi, Thiago Macieira schrieb am Fr. 17. Juli 2020 um 19:57: > On Wednesday, 15 July 2020 13:20:33 PDT Thiago Macieira wrote: > > In addition, I'd like someone to explain here: > [snip] > > 5) How you're going to fix the UB in the code generated by moc. This > requires > a satisfactory answer of C++17 or C++2a strictly compliant code, or we'll > have > to stop using this feature. > > moc generates: > > Type Klass::_qt_property_api_propertyName::value() const > { > const size_t propertyMemberOffset = > reinterpret_cast(&(static_cast *>(nullptr)->propertyName)); > const auto *thisPtr = reinterpret_cast( > reinterpret_cast(this) - propertyMemberOffset); > return thisPtr->d_func()->property.value(); > } > > The first two lines of this function are UB. > > It MUST be fixed. > This hack has been in QtQml in production since its release in 2010 (see static cast selector). It would be a shame if this stopped working :-/ Simon > ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
> On 17 Jul 2020, at 14:28, Giuseppe D'Angelo via Development > wrote: > > Il 17/07/20 14:09, Ulf Hermann ha scritto: QAction *action = ~~~; auto prop = action->text; >> This already gives you the string. You cannot retrieve the property >> itself. You can alternatively do action->text() or action->text.value(). >> They all do the same thing. > > Uhm... sorry, no, this doesn't really compute for me. Ignore the copy > semantics for a second (use const auto &, if necessary), what's > decltype(prop)? If it's QString, then you can't write .value() after it. > > >> The member to access in the private object is hardcoded in the generated >> implementation of value(). The public object to pick the private object >> from is retrieved by offset from the address of the property. moc >> generates code like this: >> qreal QQmlComponent::_qt_property_api_progress::value() const >> { >> const size_t propertyMemberOffset = >> reinterpret_cast(&(static_cast> *>(nullptr)->progress)); >> const auto *thisPtr = reinterpret_cast> *>(reinterpret_cast(this) - propertyMemberOffset); >> return thisPtr->QQmlComponent::d_func()->progress.value(); >> } >> I see where you're coming from. If the address doesn't exist, this >> shouldn't be possible. However, no_unique_address does not mean that the >> object has no address. It just means that it can share the same address >> with other objects. > > No, actually this makes perfect sense, but was contradicted before: > >> We are not casting these structs to or from anything though, do we? > > So yes, you're casting them to perform pointer arithmetic and figure out the > address of the object to get the property from. Indeed. My mistake, thanks for correcting me. When I formulated my assumption as a question, it was indeed meant that way :) Cheers, Volker ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
I must be missing something. I tend to think of eventloops with notify signals are an improvement over polling. You statement seems to say that asking for a value is better, and notifications are to be avoided? I'm not saying that you should go back to polling. In the case that you have genuine events, for example input or network activity, signals may just be the thing you need. This whole discussion is specifically about properties and their _change_ signals. Mind that the propagation of dirty flags across a binding graph is a kind of "change signal" in its own right. With QProperty, we just don't calculate the values right away when we notice that a related property has changed. Why is that? Properties can change fairly often, and synchronously triggering a chain of calculations whenever some property changes can be inefficient and can lead to unexpected intermediate values. This is why we introduce lazy evaluation for property bindings. With this system, on some level, you indeed have to poll a property to make something happen outside the system. However, certain technologies are inherently based on polling. For example the scene graph rendering a frame every 16ms will poll for changed items every time. For this, a lazy evaluation strategy makes more sense than the usual change signals. If you want to take advantage of lazy evaluation in such places, you should stop using the change signals there, though. Whenever a property has a change signal, it and everything it depends on needs to be evaluated eagerly. best, Ulf ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
Mhh, it there are no change signals anymore, i guess i also can't use QObject::connect() anymore and rather use a binding instead ? This is fine, but if two objects are living in different threads how does it work then ? With a Queued connection how it works with signals/slots is pretty clear, but in which thread is the binding evaluated ? Binding properties from different threads is not supported. Bindings should be lightweight. Usually they'd be used for closely related bits of data. Those rarely live in different threads. Building thread synchronization into bindings would make them more expensive for little gain. You can, however, still use queued signals in this scenario. QProperty has a subscribe() method, and if the change of a property is actually something you want to communicate across thread boundaries, you can attach a function that sends a signal to a QProperty via subscribe(). There is also QNotifiedProperty. I would advise against all of this, though. Sending the signal forces the property and everything it depends on to be eagerly evaluated. There likely are other ways to organize your thread synchronization. With the old properties it's also possible to define a custom behavior for the setter and getter. E.g. for the getter to not emit the changed signal, but just call a worker thread to to this and wait for the feedback to do the actual change and emit the change signal. I guess all this is not possibly anymore with the new QProperty ? If we define that behavior like this can not be done with QProperty but the old way should be used instead everything is fine, but doesn't make the API inconsistent ? You get value guards with QNotifiedProperty, and soon also with QProperty: https://codereview.qt-project.org/c/qt/qtbase/+/307894 With those, you can introspect and/or modify a new value before it is set. You can do the additional work in a value guard, and you can even reject values that way. Using a value guard does not even force eager evaluation. As I understood it, we don't want to break SC too much so we will keep all setters/getters in our API. Let's say we create a new type derived from QQuickItem and use a QProperty there, let's name this property "foo". Doesn't it mean we now have a class, which has functions like setWidth and setHeight, but not a function for setFoo ? Q_PRIVATE_QPROPERTY generates a setter, setFoo in this case, that just calls the setValue() function of the propery. If you add the property directly in the public object, you can do the same manually. best, Ulf ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
Am 17.07.20 um 19:12 schrieb Ulf Hermann: >>> I've added a section to this one. Feel free to amend. However, newly >>> designing APIs with QProperty is a different thing than converting old >>> APIs in a compatible way. >> >> The complexity behind the scenes for us to support it is our problem, >> users >> shouldn't care. >> >> They will only care that the code they write is the same, regardless of >> whether it's an old or a new class. > > Indeed the users shouldn't need to care. And they shouldn't use change > signals. Rather, they should use subscribe(), and only if they cannot > express the same thing using a binding. This way we can get rid of the > notified properties in the long run. > > So, new, QProperty-based, properties should not have change signals. > That is something users may notice, and something that needs to be > added to the API design principles. Mhh, it there are no change signals anymore, i guess i also can't use QObject::connect() anymore and rather use a binding instead ? This is fine, but if two objects are living in different threads how does it work then ? With a Queued connection how it works with signals/slots is pretty clear, but in which thread is the binding evaluated ? With the old properties it's also possible to define a custom behavior for the setter and getter. E.g. for the getter to not emit the changed signal, but just call a worker thread to to this and wait for the feedback to do the actual change and emit the change signal. I guess all this is not possibly anymore with the new QProperty ? If we define that behavior like this can not be done with QProperty but the old way should be used instead everything is fine, but doesn't make the API inconsistent ? As I understood it, we don't want to break SC too much so we will keep all setters/getters in our API. Let's say we create a new type derived from QQuickItem and use a QProperty there, let's name this property "foo". Doesn't it mean we now have a class, which has functions like setWidth and setHeight, but not a function for setFoo ? Sorry if i'm completely missunderstood on how it is supposed to work. Dominik ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Wednesday, 15 July 2020 13:20:33 PDT Thiago Macieira wrote: > In addition, I'd like someone to explain here: [snip] 5) How you're going to fix the UB in the code generated by moc. This requires a satisfactory answer of C++17 or C++2a strictly compliant code, or we'll have to stop using this feature. moc generates: Type Klass::_qt_property_api_propertyName::value() const { const size_t propertyMemberOffset = reinterpret_cast(&(static_cast(nullptr)->propertyName)); const auto *thisPtr = reinterpret_cast( reinterpret_cast(this) - propertyMemberOffset); return thisPtr->d_func()->property.value(); } The first two lines of this function are UB. It MUST be fixed. In the process, please also fix this code: auto prop = object->propertyName; return prop.value(); -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel System Software Products ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Friday, 17 July 2020 09:56:39 PDT Giuseppe D'Angelo via Development wrote: > Il 17/07/20 17:30, Thiago Macieira ha scritto: > > I will give a +2 for this patch, since I prefer it. That means adding > > properties doesn't imply an extra 8 bytes per class in the hierarchy. > > Imagine a user class hierarcy like QSctpSocket -> QTcpSocket -> > > QAbstractSocket -> QIODevice -> QObject. If each class has properties, > > that adds 40 bytes to the full size of QSctpSocket. > > > > [Yes, I know Qt-based classes should just put their properties in the d > > pointer, but users don't usually have d pointers] > > Even with d pointers, how is that supposed to work? You still need the > dummy "property object" in the class where it's declared, right? That > would still add 1 byte to the class, although that can be folded into > the alignment. > > What am I missing here? You're not, I was. You're correct, we still need the 1 byte structure added to the class. > So in your example QSctpSocket would still be 24 bytes, because the > inheritance is not deep enough to make sizeof 32? Yes, with the IA-64 ABI, assuming we don't mandate [[no_unique_address]] of course. With MSVC, it's 56 bytes. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel System Software Products ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
However, for Q_GADGET this would fall apart. Actually, with a Q_GADGET you usually don't have a private object. That's the whole point of it. Then you don't need property wrappers, either. So, to confine the property wrapper to the QObject it belongs to we can delete the copy and move constructors and assignment operators. (we still need a trick to prevent construction outside the object, though) I am confused. Removing the struct means we’re back to a setFoo()/foo() style API, and especially, we have a different API for people using Property directly and what we provide in our public API. That simply doesn’t make sense. I was assuming we'd also add setBindingOnFoo() etc. Yes, that would be different API than what we provide for QProperty directly. If we can avoid it, we should. I really want API consistency. We have QProperty as a public class for our users. Even if we need to hide our data for BC reasons, our API should not feel different than that one. Agreed, but the safety concerns Giuseppe has brought up are valid. We need to make sure the property wrappers don't escape the object they belong to. That might be possible after all, though. regards, Ulf ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Friday, 17 July 2020 09:41:16 PDT Lars Knoll wrote: > > Let's say we're going to enable it now for Linux. Ok, good. Please make > > EVERY SINGLE Qt build and user's application build unconditionally use > > [[no_unique_address]] from now until 2028. Regardless of compiler choice > > (GCC, Clang and ICC), compiler version and build flags. > > This is only about desktop linux here where we want to define an ABI. And > there we can enable it by default I think. No, it applies to everywhere where we can't guarantee the whole system is rebuilt. That applies to Mac and Windows desktops (yes, MSVC too) as well as embedded systems where an application may be compiled after Qt, with an upgraded SDK / toolchain. This happens. In other words, we should default to a fixed value, chosen RIGHT NOW. No auto- detection. Users will need to explicitly choose a different value for their platforms, if they wish. > > Here's the patch. Add qglobal.h: > > #if defined(Q_OS_LINUX) && !__has_cpp_attribute(no_unique_address) > > # error "Your compiler is too old." > > # error "Please upgrade so it supports [[no_unique_address]]." > > #endif > > > No, we error out if Qt build ABI and application builds flags are not in > sync. If you configure Qt without support for [[no_unique_address]], it’ll > work, but it’s a different build. Fair enough, a value hardcoded into qconfig.h instead Q_OS_LINUX. > > I will give a +2 for this patch, since I prefer it. That means adding > > properties doesn't imply an extra 8 bytes per class in the hierarchy. > > Imagine a user class hierarcy like QSctpSocket -> QTcpSocket -> > > QAbstractSocket -> QIODevice -> QObject. If each class has properties, > > that adds 40 bytes to the full size of QSctpSocket. > > > No, it doesn’t. It adds 4/8 bytes (unless your object hierarchy is deeper > than 4/8 levels). Since every one of those unions in the hierarchy has an > alignment requirement of 1, the property union for QIODevice will be in the > byte following the one for QObject. You're thinking of the tail padding, as in here: https://godbolt.org/z/1oreGx. Note MSVC does not use tail padding, so this discussion only applies to the IA-64 ABI (GCC, Clang, ICC). It also only applies if the union is at the tail. In our regular coding style, it wouldn't be: class K1 : public QObject { Q_OBJECT public: // property declarations private: K1Private *d; }; The union is not at the tail. So a class deriving from K1 wouldn't be able to use the tail padding. Then there's the fact that a class that adds other members would not pass on the available padding at the tail of its own to derived classes. We'd need a zig-zag of where the properties are declared in order to use that tail padding, once. class QObject { QObjectData *d_ptr; public: // properties at tail }; // sizeof: 24 class Foo1 : public QObject { public: // properties at beginning private: void *ptr; // other members at end }; // sizeof: 32 (properties used tail padding) class Foo2 : public Foo1 { public: double d; // other members at beginning // properties at end }; // sizeof: 48 class Foo3 : public Foo2 { public: // properties at beginning private: qint64 x; // other members at end }; // sizeof: 56 (tail padding used) > > [Yes, I know Qt-based classes should just put their properties in the d > > pointer, but users don't usually have d pointers] > > > Not sure what you mean here. This is only about our Q_PRIVATE_QPROPERTY, not > about the QProperty class. Oh, right, never mind. Ulf, please add this to the Coding Style: Every public class with Q_OBJECT must have Q_PRIVATE_QPROPERTIES_BEGIN / Q_PRIVATE_QPROPERTIES_END, regardless of whether it has any properties, in case someone in the future wants to add a property. No, it can't be automatic as part of Q_OBJECT. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel System Software Products ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
I've added a section to this one. Feel free to amend. However, newly designing APIs with QProperty is a different thing than converting old APIs in a compatible way. The complexity behind the scenes for us to support it is our problem, users shouldn't care. They will only care that the code they write is the same, regardless of whether it's an old or a new class. Indeed the users shouldn't need to care. And they shouldn't use change signals. Rather, they should use subscribe(), and only if they cannot express the same thing using a binding. This way we can get rid of the notified properties in the long run. So, new, QProperty-based, properties should not have change signals. That is something users may notice, and something that needs to be added to the API design principles. best, Ulf ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On 17/07/20 19:00, Thiago Macieira wrote: On Friday, 17 July 2020 09:34:54 PDT Lars Knoll wrote: I'll just post this and let you ponder the consequences of this choice for Linux: https://godbolt.org/z/nhex5x Yes, that’s why we need to encode that into a static_assert(). But the support it coming to all compilers and Linux desktops will support the feature both with gcc and clang. I’m pretty sure ICC will follow soon. Sure. But to be clear: we're saying the MINIMUM versions of GCC and Clang for Qt 6.0 are 9.0. GCC 9 was released in May 2019 and LLVM 9 was released in September 2019. Apple Clang in the current XCode does NOT support it. Versions of mainstream Linux distributions with GCC 9: * Debian: testing * Fedora: 30 * openSUSE: 15.2 * Ubuntu: 19.10 (Arch, Clear, Gentoo are rolling releases) If you're not working from home, go around in the office and ask who's running anything older. Maybe use the GCC extension of using an empty array: https://godbolt.org/z/MvE9jf ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Friday, 17 July 2020 09:34:54 PDT Lars Knoll wrote: > > I'll just post this and let you ponder the consequences of this choice for > > Linux: > > https://godbolt.org/z/nhex5x > > Yes, that’s why we need to encode that into a static_assert(). But the > support it coming to all compilers and Linux desktops will support the > feature both with gcc and clang. I’m pretty sure ICC will follow soon. Sure. But to be clear: we're saying the MINIMUM versions of GCC and Clang for Qt 6.0 are 9.0. GCC 9 was released in May 2019 and LLVM 9 was released in September 2019. Apple Clang in the current XCode does NOT support it. Versions of mainstream Linux distributions with GCC 9: * Debian: testing * Fedora: 30 * openSUSE: 15.2 * Ubuntu: 19.10 (Arch, Clear, Gentoo are rolling releases) If you're not working from home, go around in the office and ask who's running anything older. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel System Software Products ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
> On 17 Jul 2020, at 15:01, Ulf Hermann wrote: > > QAction *action = ~~~; > auto prop = action->text; >>> This already gives you the string. You cannot retrieve the property >>> itself. You can alternatively do action->text() or action->text.value(). >>> They all do the same thing. >> Uhm... sorry, no, this doesn't really compute for me. Ignore the copy >> semantics for a second (use const auto &, if necessary), what's >> decltype(prop)? If it's QString, then you can't write .value() after it. > > OK, I got you wrong, and I was confused about the cast operators in QProperty > and the property wrappers. Sorry. Indeed "auto prop = action->text;" would > give you a useless object that pokes random memory whenever you invoke any > method of it. That needs to be fixed indeed. You should not be able to copy > the property wrapper out of the object. For properties on QObject that would > be easy as QObject itself is not copyable. We could just =delete the copy > ctor and assignment operators. We might also prevent external construction of > the struct by having some "secret" extra argument, kind of like > QPrivateSignal. Right, using auto for the return value is something we need to think about a bit more. > > However, for Q_GADGET this would fall apart. > > For reference, Q_PRIVATE_QPROPERTY looks like this: > > #define Q_PRIVATE_QPROPERTY(accessor, type, name, setter, ...) \ >struct _qt_property_api_##name { \ >type value() const; \ >type operator()() const { return value(); } \ >void setValue(type &&); \ >void setValue(type const &); \ >void operator=(type const &v) { setValue(v); } \ >void operator=(type &&v) { setValue(std::move(v)); } \ >QPropertyBinding setBinding(const QPropertyBinding > &); \ >QPropertyBinding setBinding(QPropertyBinding &&); \ >QPropertyBinding operator=(const QPropertyBinding > &b) { return setBinding(b); } \ >QPropertyBinding operator=(QPropertyBinding &&b) { > return setBinding(std::move(b)); } \ >bool setBinding(const QUntypedPropertyBinding &); \ >template \ >QPropertyBinding setBinding(Functor f, \ > const > QPropertyBindingSourceLocation &location = > QT_PROPERTY_DEFAULT_BINDING_LOCATION) \ >{ \ >return setBinding(Qt::makePropertyBinding(f, location)); \ >} \ >bool hasBinding() const; \ >QPropertyBinding binding() const; \ >QPropertyBinding takeBinding(); \ >}; \ >void setter(type const& value); > > So, in fact we need to rework this and provide only methods instead of a > struct. Now we need a naming convention for all those methods and some way of > avoiding name clashes. I am confused. Removing the struct means we’re back to a setFoo()/foo() style API, and especially, we have a different API for people using Property directly and what we provide in our public API. That simply doesn’t make sense. > If QNotifiedProperty didn't need members of the private object as template > parameters, we could just have one extra method that retrieves a reference to > the underlying Q(Notified)Property (or rather two: const and non-const). > >> No, actually this makes perfect sense, but was contradicted before: >>> We are not casting these structs to or from anything though, do we? > > That statement was wrong. We do need to cast the structs. Another argument > for eliminating them. I really want API consistency. We have QProperty as a public class for our users. Even if we need to hide our data for BC reasons, our API should not feel different than that one. We’ve had a couple of ideas behind the design of the new property API: * Allow for bindings from C++ Bindings in C++ are a killer feature for Qt 6. It was what made QML so successful over the last years. It’s also one of the things that enabled the huge performance gains we were able to achieve in Qt for MCU. * Easy and transparent in its usage Qt’s API and the interface we provide to our users should be the same. QProperty must hide it’s storage completely, so we can guarantee that bindings will work. For that we do need a QProperty class * Ideally a “real” property style API that also other languages provide If you have a property, I simply want to assign a value to it, or assign from it to read out the value. That might not be 100% achievable given the ‘auto’ problem pointed out above, but it would be great if we could. Cheers, Lars ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
Il 17/07/20 17:30, Thiago Macieira ha scritto: I will give a +2 for this patch, since I prefer it. That means adding properties doesn't imply an extra 8 bytes per class in the hierarchy. Imagine a user class hierarcy like QSctpSocket -> QTcpSocket -> QAbstractSocket -> QIODevice -> QObject. If each class has properties, that adds 40 bytes to the full size of QSctpSocket. [Yes, I know Qt-based classes should just put their properties in the d pointer, but users don't usually have d pointers] Even with d pointers, how is that supposed to work? You still need the dummy "property object" in the class where it's declared, right? That would still add 1 byte to the class, although that can be folded into the alignment. What am I missing here? class QObject { QObjectPrivate *d_ptr; public: virtual ~QObject(); union { P1 objectName; P2 somethingElse; }; }; /* alignof == 8, sizeof == 24 (8 vptr + 8 d_ptr + 1 union + 7 padding) */ class QWidget : public QObject /*, QPaintDevice, I know */ { public: union { P3 visible; P4 geometry; }; }; /* alignof == 8, sizeof still 24 (23 for the base class + 1 union + 6 padding) */ So in your example QSctpSocket would still be 24 bytes, because the inheritance is not deep enough to make sizeof 32? Thanks, -- Giuseppe D'Angelo | giuseppe.dang...@kdab.com | Senior Software Engineer KDAB (France) S.A.S., a KDAB Group company Tel. France +33 (0)4 90 84 08 53, http://www.kdab.com KDAB - The Qt, C++ and OpenGL Experts smime.p7s Description: Firma crittografica S/MIME ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
> On 17 Jul 2020, at 17:30, Thiago Macieira wrote: > > On Friday, 17 July 2020 00:25:04 PDT Lars Knoll wrote: >> Yes, it can and it does work. And it’s what we should be doing on compilers >> that support [[no_unique_address]]. > > The problem is that you can't change your mind, since it affects binary > compatibility. See https://godbolt.org/z/oExfzP: > > struct Union > { >struct Empty {}; >union { >Empty e; >}; >void *dummy; > }; > struct NoUniqueAddress > { >struct Empty {}; >[[no_unique_address]] Empty e; >void *dummy; > }; > > These two structures do not have the same size and the offset of "dummy" in > each is also different. That means the choice of using [[no_unique_address]] > or not using it must be made RIGHT NOW and cannot be changed. It’s a choice that has to be made when building Qt, similar to what we had with qreal=float/double in the past. > > Let's say we're going to enable it now for Linux. Ok, good. Please make EVERY > SINGLE Qt build and user's application build unconditionally use > [[no_unique_address]] from now until 2028. Regardless of compiler choice > (GCC, > Clang and ICC), compiler version and build flags. This is only about desktop linux here where we want to define an ABI. And there we can enable it by default I think. > > Here's the patch. Add qglobal.h: > #if defined(Q_OS_LINUX) && !__has_cpp_attribute(no_unique_address) > # error "Your compiler is too old." > # error "Please upgrade so it supports [[no_unique_address]]." > #endif No, we error out if Qt build ABI and application builds flags are not in sync. If you configure Qt without support for [[no_unique_address]], it’ll work, but it’s a different build. > > I will give a +2 for this patch, since I prefer it. That means adding > properties doesn't imply an extra 8 bytes per class in the hierarchy. Imagine > a user class hierarcy like QSctpSocket -> QTcpSocket -> QAbstractSocket -> > QIODevice -> QObject. If each class has properties, that adds 40 bytes to the > full size of QSctpSocket. No, it doesn’t. It adds 4/8 bytes (unless your object hierarchy is deeper than 4/8 levels). Since every one of those unions in the hierarchy has an alignment requirement of 1, the property union for QIODevice will be in the byte following the one for QObject. > > [Yes, I know Qt-based classes should just put their properties in the d > pointer, but users don't usually have d pointers] Not sure what you mean here. This is only about our Q_PRIVATE_QPROPERTY, not about the QProperty class. Cheers, Lars > -- > Thiago Macieira - thiago.macieira (AT) intel.com > Software Architect - Intel System Software Products > > > > ___ > Development mailing list > Development@qt-project.org > https://lists.qt-project.org/listinfo/development ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
> On 17 Jul 2020, at 17:50, Thiago Macieira wrote: > > On Friday, 17 July 2020 02:05:48 PDT Lars Knoll wrote: >> Some older embedded toolchains don’t have the flag neither. > > Then give them an option to opt out, at Qt configure time. That's a flag on > the same level as using -mfloat-abi=softfp instead of -mfloat-abi=hard or > using -stdlib=libc++ for Clang: completely ABI incompatible. But embedded > devices that build everything for the image in question can afford to make > ABI > choices per version. A configure option is perfectly fine for me :) > > The same configure (ahem, cmake!) flag can be used to turn it on when it > isn't > on by default. Such as when a new version of a compiler supports in 2021 or > later. Read: MSVC. > > You may want to add this fact to archdetect.cpp (QSysInfo::buildAbi()). We > can > also fix this automatically by having a variable that depends on the size of > QObject. > > I'll just post this and let you ponder the consequences of this choice for > Linux: > https://godbolt.org/z/nhex5x Yes, that’s why we need to encode that into a static_assert(). But the support it coming to all compilers and Linux desktops will support the feature both with gcc and clang. I’m pretty sure ICC will follow soon. Lars ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Friday, 17 July 2020 04:59:12 PDT Ulf Hermann wrote: > > Quite a few wiki pages could do with an update: most obviously: > > https://wiki.qt.io/API_Design_Principles > > I've added a section to this one. Feel free to amend. However, newly > designing APIs with QProperty is a different thing than converting old > APIs in a compatible way. The complexity behind the scenes for us to support it is our problem, users shouldn't care. They will only care that the code they write is the same, regardless of whether it's an old or a new class. -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel System Software Products ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Friday, 17 July 2020 04:54:08 PDT Giuseppe D'Angelo via Development wrote: > Il 16/07/20 17:40, Volker Hilsheimer ha scritto: > > The struct has no data itself, so ideally would be of size zero. > > I'm missing some piece of the puzzle: if you take action->text, and text > is a zero-size struct, how does the operator() applied to it figure out > which action needs to read the text property from? E.g. like so: The same way this works: auto l1 = [] { return 1; }; auto l2 = [] { return 2; }; Both l1 and l2 are "zero" sized closure types with an operator(). When you call them, you get different results, because the C++ compiler will place a call to different functions. Note: that's different from: auto f1 = +[] { return 1; }; auto f2 = +[] { return 2; }; The unary + forces the stateless lambda to cast to void(void), so f1 and f2 are the same type (a function pointer) and have different values. > > QAction *action = ~~~; > > auto prop = action->text; > > QString text = prop(); Note on the above: the type should not have a cast operator. Otherwise: auto prop = action->text; QString value = action->text; would be different things. Not to mention QString builder failures. People should always write action->text(). -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel System Software Products ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Friday, 17 July 2020 00:25:04 PDT Lars Knoll wrote: > Yes, it can and it does work. And it’s what we should be doing on compilers > that support [[no_unique_address]]. The problem is that you can't change your mind, since it affects binary compatibility. See https://godbolt.org/z/oExfzP: struct Union { struct Empty {}; union { Empty e; }; void *dummy; }; struct NoUniqueAddress { struct Empty {}; [[no_unique_address]] Empty e; void *dummy; }; These two structures do not have the same size and the offset of "dummy" in each is also different. That means the choice of using [[no_unique_address]] or not using it must be made RIGHT NOW and cannot be changed. Let's say we're going to enable it now for Linux. Ok, good. Please make EVERY SINGLE Qt build and user's application build unconditionally use [[no_unique_address]] from now until 2028. Regardless of compiler choice (GCC, Clang and ICC), compiler version and build flags. Here's the patch. Add qglobal.h: #if defined(Q_OS_LINUX) && !__has_cpp_attribute(no_unique_address) # error "Your compiler is too old." # error "Please upgrade so it supports [[no_unique_address]]." #endif I will give a +2 for this patch, since I prefer it. That means adding properties doesn't imply an extra 8 bytes per class in the hierarchy. Imagine a user class hierarcy like QSctpSocket -> QTcpSocket -> QAbstractSocket -> QIODevice -> QObject. If each class has properties, that adds 40 bytes to the full size of QSctpSocket. [Yes, I know Qt-based classes should just put their properties in the d pointer, but users don't usually have d pointers] -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel System Software Products ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
On Friday, 17 July 2020 02:05:48 PDT Lars Knoll wrote: > Some older embedded toolchains don’t have the flag neither. Then give them an option to opt out, at Qt configure time. That's a flag on the same level as using -mfloat-abi=softfp instead of -mfloat-abi=hard or using -stdlib=libc++ for Clang: completely ABI incompatible. But embedded devices that build everything for the image in question can afford to make ABI choices per version. The same configure (ahem, cmake!) flag can be used to turn it on when it isn't on by default. Such as when a new version of a compiler supports in 2021 or later. Read: MSVC. You may want to add this fact to archdetect.cpp (QSysInfo::buildAbi()). We can also fix this automatically by having a variable that depends on the size of QObject. I'll just post this and let you ponder the consequences of this choice for Linux: https://godbolt.org/z/nhex5x -- Thiago Macieira - thiago.macieira (AT) intel.com Software Architect - Intel System Software Products ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
Il 17/07/20 11:36, Lars Knoll ha scritto: And it’s cleaner, because using the union trick, we do access several members of the union at the same time. It works on all compilers but I’m not 100% convinced it’s fully defined behavior according to C++, even if the members don’t have data. To me, it's mostly the pointer arithmetic being sketchy (although probably legal). I don't see a particular problem with the union trick -- given N empty classes class Ex {}; And then the union union U { E1 e1; E2 e2; ~~~ EN en; }; Then: 1) All of Ex and therefore U are standard layout classes [class.prop] 2) Therefore, the address of U is the same address as E1 [class.mem§26] 3) All non static data members of U have the same address [class.union] It follows that U and all of its inner EN subobjects have the same address, so you can apply the same offset to all of them reach the QObject/gadget that contains U as subobject. And why wouldn’t we do it, if the compilers support it? Because it breaks ABI, and only relatively recent GCC versions have support for the attribute... or does GCC have a nonstandard one? Thanks, -- Giuseppe D'Angelo | giuseppe.dang...@kdab.com | Senior Software Engineer KDAB (France) S.A.S., a KDAB Group company Tel. France +33 (0)4 90 84 08 53, http://www.kdab.com KDAB - The Qt, C++ and OpenGL Experts smime.p7s Description: Firma crittografica S/MIME ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
Hi Ulf, > QProperty's main feature is accepting lazily evaluated bindings in place of a plain value. It can also notify eagerly if you use the subscribe() and onValueChanged() methods, but you'd usually avoid that as best as you can. I must be missing something. I tend to think of eventloops with notify signals are an improvement over polling. You statement seems to say that asking for a value is better, and notifications are to be avoided? At some level, I'm looking for an example of why this is a step forward. I don't mean to suggest it _isn't_ a step forward, just that I don't see it yet. Thanks, Brett ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
QAction *action = ~~~; auto prop = action->text; This already gives you the string. You cannot retrieve the property itself. You can alternatively do action->text() or action->text.value(). They all do the same thing. Uhm... sorry, no, this doesn't really compute for me. Ignore the copy semantics for a second (use const auto &, if necessary), what's decltype(prop)? If it's QString, then you can't write .value() after it. OK, I got you wrong, and I was confused about the cast operators in QProperty and the property wrappers. Sorry. Indeed "auto prop = action->text;" would give you a useless object that pokes random memory whenever you invoke any method of it. That needs to be fixed indeed. You should not be able to copy the property wrapper out of the object. For properties on QObject that would be easy as QObject itself is not copyable. We could just =delete the copy ctor and assignment operators. We might also prevent external construction of the struct by having some "secret" extra argument, kind of like QPrivateSignal. However, for Q_GADGET this would fall apart. For reference, Q_PRIVATE_QPROPERTY looks like this: #define Q_PRIVATE_QPROPERTY(accessor, type, name, setter, ...) \ struct _qt_property_api_##name { \ type value() const; \ type operator()() const { return value(); } \ void setValue(type &&); \ void setValue(type const &); \ void operator=(type const &v) { setValue(v); } \ void operator=(type &&v) { setValue(std::move(v)); } \ QPropertyBinding setBinding(const QPropertyBinding &); \ QPropertyBinding setBinding(QPropertyBinding &&); \ QPropertyBinding operator=(const QPropertyBinding &b) { return setBinding(b); } \ QPropertyBinding operator=(QPropertyBinding &&b) { return setBinding(std::move(b)); } \ bool setBinding(const QUntypedPropertyBinding &); \ template \ QPropertyBinding setBinding(Functor f, \ const QPropertyBindingSourceLocation &location = QT_PROPERTY_DEFAULT_BINDING_LOCATION) \ { \ return setBinding(Qt::makePropertyBinding(f, location)); \ } \ bool hasBinding() const; \ QPropertyBinding binding() const; \ QPropertyBinding takeBinding(); \ }; \ void setter(type const& value); So, in fact we need to rework this and provide only methods instead of a struct. Now we need a naming convention for all those methods and some way of avoiding name clashes. If QNotifiedProperty didn't need members of the private object as template parameters, we could just have one extra method that retrieves a reference to the underlying Q(Notified)Property (or rather two: const and non-const). No, actually this makes perfect sense, but was contradicted before: We are not casting these structs to or from anything though, do we? That statement was wrong. We do need to cast the structs. Another argument for eliminating them. best, Ulf ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development
Re: [Development] QProperty and library coding guide
item->width.setBinding([]() { return otherItem->height(); }); ... item->widthSetBinding([]() { return otherItem->height(); }); ... See the definition of Q_PRIVATE_QPROPERTY for the different methods we generate into the structs. It sounds like there are two overlapping elements to these changes. First is the ability to compress getters/setters/onChanged in to a single name, and second, an extension to allow "lazy" binding? Is this correct? I understand the struct would allow both, I'm asking about the intent, not the implementation. I.e., how this is expected to be used. If you start your exploration from Q_PRIVATE_QPROPERTY with NOTIFY it's all backwards and you're going to have a hard time understanding what it's all about. I recommend starting from plain QProperty. QProperty's main feature is accepting lazily evaluated bindings in place of a plain value. It can also notify eagerly if you use the subscribe() and onValueChanged() methods, but you'd usually avoid that as best as you can. A QProperty can be exposed to the metaobject system using a simplified Q_PROPERTY macro: class Xyz : public QObject { Q_OBJECT Q_PROPERTY(int someInt) public: QProperty someInt; }; This looks much nicer than all the other stuff we've been discussing, doesn't it? This is what I envision for most user code. However, we don't want to follow this pattern in our public API, because QProperty has a size and we want to be able to extend our public classes without increasing the size. Therefore, Q_PRIVATE_QPROPERTY was invented. Q_PRIVATE_QPROPERTY creates an almost size-less wrapper around a QProperty living in the private object. The idea is that the wrapper provides the same interface as QProperty, and therefore it's a somewhat unpleasant looking struct with a number of methods but no data members. That aspect could be changed. On top of this, a plain QProperty doesn't know the object it belongs to. Therefore, it cannot send signals on behalf of that object from it's subscribe callback. In order to enable backwards compatibility with properties that do send signals, QNotifiedProperty was invented. QNotifiedProperty takes the pointer to the owning object as argument for every method that might require sending a signal. It then invokes a callback on that object as notification. That is really not the nicest thing to use, but luckily we only need it for those old properties that still require change signals. Once we can get rid of all the change signals, we won't need QNotifiedProperty anymore. As most of the getter/setter/signal properties in public API do indeed have signals, we then get to wrap QNotifiedProperty into Q_PRIVATE_QPROPERTY, and you can ask the protagonists of the interest mailing list drama for the best words to describe that. Yet, again, this is only for compatibility reasons, and we should strive to eventually get rid of those warts, or at least not produce new ones in new code. best, Ulf ___ Development mailing list Development@qt-project.org https://lists.qt-project.org/listinfo/development