Re: [Development] QProperty and library coding guide

2020-07-24 Thread Thiago Macieira
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

2020-07-24 Thread Ville Voutilainen
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

2020-07-24 Thread Lisandro Damián Nicanor Pérez Meyer
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

2020-07-24 Thread Ville Voutilainen
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

2020-07-24 Thread Thiago Macieira
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

2020-07-24 Thread Stottlemyer, Brett (B.S.)
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

2020-07-24 Thread Thiago Macieira
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

2020-07-24 Thread James McDonnell
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

2020-07-24 Thread Olivier Goffart

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

2020-07-23 Thread Thiago Macieira
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

2020-07-23 Thread Thiago Macieira
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

2020-07-23 Thread Thiago Macieira
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

2020-07-23 Thread Henry Skoglund

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

2020-07-23 Thread Thiago Macieira
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

2020-07-23 Thread Ville Voutilainen
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

2020-07-23 Thread Ville Voutilainen
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

2020-07-23 Thread Thiago Macieira
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

2020-07-23 Thread Bernhard Lindner

> > 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

2020-07-23 Thread Simon Hausmann
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

2020-07-23 Thread André Pönitz
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

2020-07-22 Thread Thiago Macieira
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

2020-07-22 Thread Bernhard Lindner
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

2020-07-22 Thread Thiago Macieira
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

2020-07-22 Thread André Pönitz
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

2020-07-22 Thread Thiago Macieira
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

2020-07-22 Thread Thiago Macieira
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

2020-07-22 Thread Simon Hausmann
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

2020-07-22 Thread Lars Knoll


> 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

2020-07-22 Thread Thiago Macieira
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

2020-07-22 Thread André Somers


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

2020-07-22 Thread Lars Knoll
> 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

2020-07-22 Thread Lars Knoll
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

2020-07-22 Thread Lars Knoll
> 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

2020-07-22 Thread Shawn Rutledge

> 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

2020-07-21 Thread Thiago Macieira
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

2020-07-21 Thread Thiago Macieira
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

2020-07-21 Thread Thiago Macieira
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

2020-07-21 Thread Ville Voutilainen
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

2020-07-21 Thread Volker Hilsheimer
> 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

2020-07-21 Thread Ville Voutilainen
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

2020-07-21 Thread Ville Voutilainen
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

2020-07-21 Thread Thiago Macieira
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

2020-07-21 Thread Ville Voutilainen
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

2020-07-21 Thread Volker Hilsheimer
> 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

2020-07-21 Thread Thiago Macieira
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

2020-07-21 Thread Fabian Kosmale
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

2020-07-21 Thread Volker Hilsheimer


> 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

2020-07-20 Thread Thiago Macieira
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

2020-07-20 Thread Thiago Macieira
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

2020-07-20 Thread Giuseppe D'Angelo via Development

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

2020-07-20 Thread Thiago Macieira
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

2020-07-20 Thread Ville Voutilainen
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

2020-07-20 Thread Thiago Macieira
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

2020-07-20 Thread Oswald Buddenhagen

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

2020-07-20 Thread Thiago Macieira
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

2020-07-20 Thread Jaroslaw Kobus
> 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

2020-07-20 Thread Lars Knoll


> 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

2020-07-19 Thread Thiago Macieira
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

2020-07-19 Thread André Somers


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

2020-07-19 Thread Giuseppe D'Angelo via Development

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

2020-07-19 Thread Ville Voutilainen
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

2020-07-19 Thread Thiago Macieira
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

2020-07-19 Thread Thiago Macieira
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

2020-07-19 Thread Ville Voutilainen
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

2020-07-19 Thread Oswald Buddenhagen

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

2020-07-19 Thread Giuseppe D'Angelo via Development

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

2020-07-19 Thread Giuseppe D'Angelo via Development

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

2020-07-19 Thread Oswald Buddenhagen

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

2020-07-19 Thread Sze Howe Koh
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

2020-07-18 Thread Giuseppe D'Angelo via Development

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

2020-07-18 Thread Thiago Macieira
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

2020-07-18 Thread Thiago Macieira
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

2020-07-18 Thread Giuseppe D'Angelo via Development

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

2020-07-18 Thread Giuseppe D'Angelo via Development

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

2020-07-18 Thread Arno Rehn
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

2020-07-18 Thread Dominik Holland
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

2020-07-17 Thread Simon Hausmann
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

2020-07-17 Thread Volker Hilsheimer


> 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

2020-07-17 Thread Ulf Hermann
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

2020-07-17 Thread 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.



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

2020-07-17 Thread Dominik Holland
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

2020-07-17 Thread Thiago Macieira
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

2020-07-17 Thread Thiago Macieira
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

2020-07-17 Thread 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.

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

2020-07-17 Thread Thiago Macieira
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

2020-07-17 Thread 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.


best,
Ulf
___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] QProperty and library coding guide

2020-07-17 Thread Olivier Goffart

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

2020-07-17 Thread Thiago Macieira
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

2020-07-17 Thread Lars Knoll
> 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

2020-07-17 Thread Giuseppe D'Angelo via Development

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

2020-07-17 Thread Lars Knoll
> 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

2020-07-17 Thread Lars Knoll

> 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

2020-07-17 Thread Thiago Macieira
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

2020-07-17 Thread Thiago Macieira
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

2020-07-17 Thread Thiago Macieira
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

2020-07-17 Thread Thiago Macieira
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

2020-07-17 Thread Giuseppe D'Angelo via Development

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

2020-07-17 Thread Stottlemyer, Brett (B.S.)
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

2020-07-17 Thread Ulf Hermann

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

2020-07-17 Thread Ulf Hermann

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


  1   2   >