Re: [Development] unique_ptr and Qt, Take 2

2019-06-21 Thread Daniel Teske



The minor problem being that to not so small audiences,
new Whoosh(something);
just looks like a bug, and then you need to look three times to
realize that something is a parent.

Sure... but `something.createChild()` can help with that.

OTOH, I just realized a problem with that... when the new child needs to
take its parent in the ctor for other reasons. I don't know if there is
an easy solution to that. (Of course, you can still pass the parent with
createChild, but then you've violated DRY.)


There are multiple different implementations of createChild.

The one I did choose requires the class to have a tagged ctor, meaning a 
ctor whose first parameter is QParentPtr parent, so the ctor 
still has access to the actual parent ptr, and createChild simply passes 
the this pointer as the first parameter.


The drawback is obviously that requires new ctors, but there are several 
benefits:


* It is easier to do than having a later reparenting. Writing the new 
ctors is trivial.

* It allows for designing classes that can only created with a parent
* The cost of creating new ctors is only for those that want to make use 
of createChild.

* The new ctors have clear ownership semantics

In that patch, I've also added new ctors that take no parent ptr, to be 
used with make_unique or for stack-allocation.


And the last puzzle piece is that the qt users can choose to deprecate 
the old existing ctors, thus users can choose between:


* Keep just using Qt as is
* Make use of createChild by providing new ctors
* Ensure that each memory allocation is either parented or held in a 
unique_ptr, by opting into the deprecation + using some kind of code 
analysis preventing usage of raw news.


And obviously that's also the way, a existing code base could be 
transitioned.


The actual implementation of that mechanism is in:

https://codereview.qt-project.org/c/qt/qtbase/+/260618/1/src/corelib/global/qglobal.h 

https://codereview.qt-project.org/c/qt/qtbase/+/260618/1/src/corelib/kernel/qobjectdefs.h 



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


Re: [Development] unique_ptr and Qt, Take 2

2019-06-17 Thread Matthew Woehlke
On 15/06/2019 14.24, Ville Voutilainen wrote:
> On Sat, 15 Jun 2019 at 02:30, Matthew Woehlke  
> wrote:
 OTOH, I just realized a problem with that... when the new child needs to
 take its parent in the ctor for other reasons. I don't know if there is
 an easy solution to that. (Of course, you can still pass the parent with
 createChild, but then you've violated DRY.)
>>>
>>> That seems like a fairly minor problem. We either just pass the
>>> parent in, or make createChild do the child construction with the
>>> parent as an argument if that's valid, or fall back to reparenting if
>>> not.
>>
>> I don't think createChild can/should assume that a QObject* ctor
>> parameter means "parent", i.e. it should *always* explicitly reparent.
> 
> We should perhaps look at whether it could assume it. Or add overloads
> that do/don't.

Overloads could work.

I think assuming could be dangerous in the face of user types, but OTOH
maybe we should make it part of the API that if you have such types, you
are expected to provide a template specialization for your type that
Does The Right Thing.

The more I think about it, the more I suspect that's just the right
solution... make it work for Qt's own classes and user classes that
strictly follow "the rules", and just tell people to specialize it (or
just don't use it) otherwise, rather than trying to overengineer things.

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


Re: [Development] unique_ptr and Qt, Take 2

2019-06-15 Thread Ville Voutilainen
On Sat, 15 Jun 2019 at 02:30, Matthew Woehlke  wrote:
> >> OTOH, I just realized a problem with that... when the new child needs to
> >> take its parent in the ctor for other reasons. I don't know if there is
> >> an easy solution to that. (Of course, you can still pass the parent with
> >> createChild, but then you've violated DRY.)
> >
> > That seems like a fairly minor problem. We either just pass the
> > parent in, or make createChild do the child construction with the
> > parent as an argument if that's valid, or fall back to reparenting if
> > not.
>
> I don't think createChild can/should assume that a QObject* ctor
> parameter means "parent", i.e. it should *always* explicitly reparent.

We should perhaps look at whether it could assume it. Or add overloads
that do/don't.

>
> So I don't see a way that such classes can avoid writing:
>
>   parent.createChild(parent, ...);
>
> ...which means we wrote 'parent' twice, vs.:
>
>   new Whoosh(parent);

Yeah, and that seems like a very minor problem to me.

> >>> [...] the largeish application was leaking like a sieve and doing
> >>> use-after-free in all too many places.
> >>
> >> QPointer is great for avoiding this :-). (Also, properly "owned"
> >> signal/slot connections.)
> >
> > I fail to see how QPointer helps with that,
>
> Proper use of QPointer can certainly help with use-after-free.

Right, but not with automatic cleanup.


> > I don't know what to do with that. You asked whether there's a WIP,
> > and after being pointed to such a WIP, you are applying a yardstick
> > to it and then saying that you're discouraged from even looking at
> > it, because it violates your arbitrary yardstick requirement.
> I suggested that perhaps folks were intimidated by Daniel's proposal
> because "modifying every method, everywhere, that reparents a QObject is
> a little intimidating." As I'd overlooked the patch, I was just guessing
> at how much churn there would be. Subsequently looking at the patch
> confirmed my suspicion.
>
> IOW:
>
> Me:  opinion>
> You: 
> Me: Okay, sticking with my original conjecture.
>
> I don't know what to do with your "arbitrary yardstick" comment. Large
> code changes tend to be intimidating, and (in many cases) rightly so.

To each their own. Large and complicated changes being intimidating I
can have sympathy
for, large and simple changes not so much.
___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] unique_ptr and Qt, Take 2

2019-06-14 Thread Matthew Woehlke
On 14/06/2019 17.05, Ville Voutilainen wrote:
> On Fri, 14 Jun 2019 at 00:36, Matthew Woehlke wrote:
>> On 13/06/2019 16.09, Ville Voutilainen wrote:
>>> The minor problem being that to not so small audiences,
>>> new Whoosh(something);
>>> just looks like a bug, and then you need to look three times to
>>> realize that something is a parent.
>>
>> Sure... but `something.createChild()` can help with that.
>>
>> OTOH, I just realized a problem with that... when the new child needs to
>> take its parent in the ctor for other reasons. I don't know if there is
>> an easy solution to that. (Of course, you can still pass the parent with
>> createChild, but then you've violated DRY.)
> 
> That seems like a fairly minor problem. We either just pass the
> parent in, or make createChild do the child construction with the
> parent as an argument if that's valid, or fall back to reparenting if
> not.

I don't think createChild can/should assume that a QObject* ctor
parameter means "parent", i.e. it should *always* explicitly reparent.

So I don't see a way that such classes can avoid writing:

  parent.createChild(parent, ...);

...which means we wrote 'parent' twice, vs.:

  new Whoosh(parent);

OTOH I don't think such classes are common. (I know my own code contains
a few, but I'm not sure there are any in Qt itself.)

>>> [...] the largeish application was leaking like a sieve and doing
>>> use-after-free in all too many places.
>>
>> QPointer is great for avoiding this :-). (Also, properly "owned"
>> signal/slot connections.)
> 
> I fail to see how QPointer helps with that,

Proper use of QPointer can certainly help with use-after-free.

> nor do I know what "properly owned" signal/slot connections are.

Connections which have both a sender and receiver owner, such that they
disappear when *either* is destroyed... and in particular, when the
receiver is the owner of any resources used in the slot. (Although, this
really only became relevant with Qt5 when you could use lambdas as slots.)

>>> On Thu, 13 Jun 2019 at 22:54, Matthew Woehlke wrote:
 My "concern", and possibly why everyone fixated on the unique_ptr stuff,
 is how wide-sweeping the necessary API changes will be. Modifying every
 method, everywhere, that reparents a QObject is a little intimidating.
 (Maybe you have some WIP that can put this into perspective?)
>>>
>>> Like https://codereview.qt-project.org/c/qt/qtbase/+/260618 ?
>>
>> Uh... yeah, I suppose. And... yeah. Yike. That's a scary (or at least
>> intimidating) amount of API churn. In particular, there are enough files
>> being touched to strongly discourage me even looking at the diffs...
> 
> I don't know what to do with that. You asked whether there's a WIP, 
> and after being pointed to such a WIP, you are applying a yardstick
> to it and then saying that you're discouraged from even looking at
> it, because it violates your arbitrary yardstick requirement.
I suggested that perhaps folks were intimidated by Daniel's proposal
because "modifying every method, everywhere, that reparents a QObject is
a little intimidating." As I'd overlooked the patch, I was just guessing
at how much churn there would be. Subsequently looking at the patch
confirmed my suspicion.

IOW:

Me: 
You: 
Me: Okay, sticking with my original conjecture.

I don't know what to do with your "arbitrary yardstick" comment. Large
code changes tend to be intimidating, and (in many cases) rightly so.

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


Re: [Development] unique_ptr and Qt, Take 2

2019-06-14 Thread Ville Voutilainen
On Fri, 14 Jun 2019 at 00:36, Matthew Woehlke  wrote:
>
> On 13/06/2019 16.09, Ville Voutilainen wrote:
> > The minor problem being that to not so small audiences,
> > new Whoosh(something);
> > just looks like a bug, and then you need to look three times to
> > realize that something is a parent.
>
> Sure... but `something.createChild()` can help with that.
>
> OTOH, I just realized a problem with that... when the new child needs to
> take its parent in the ctor for other reasons. I don't know if there is
> an easy solution to that. (Of course, you can still pass the parent with
> createChild, but then you've violated DRY.)

That seems like a fairly minor problem. We either just pass the parent
in, or make createChild
do the child construction with the parent as an argument if that's
valid, or fall back to reparenting
if not.

> >> That's one of the things I love about Qt; object hierarchies give me
> >> working dynamic memory management without needing even smart pointers.
> >
> > That's the one thing that makes me queasy about using Qt in large
> > applications; I always need to worry about ownership relationships,
> > because I can't program with smart pointers.
> I guess your mileage varies. My experience has been the opposite.
>
> To be fair, I expect a lot of that is "instinctive"... that is, when you
> come from a background where not using smart pointers is scary, the Qt
> way is probably going to rub you the wrong way, even though it's nowhere
> near as dangerous as your experience causes you to believe. Conversely,

My experience with Qt matches my previous experience. Memory leaks are
easy to introduce, and avoiding them is not trivial.

> being comfortable with Qt and its minimal need for smart pointers likely
> produces an aversion to sprinkling them everywhere "because it's safer".

Interesting conjecture; there's no quotation marks in the actual
rationale for programming
with smart pointers without using raw pointers across a codebase, and
that reason is
that it's proven to work.

> > [...] the largeish application was leaking like a sieve and doing
> > use-after-free in all too many places.
>
> QPointer is great for avoiding this :-). (Also, properly "owned"
> signal/slot connections.)

I fail to see how QPointer helps with that, nor do I know what
"properly owned" signal/slot connections
are.

> > On Thu, 13 Jun 2019 at 22:54, Matthew Woehlke wrote:
> >> My "concern", and possibly why everyone fixated on the unique_ptr stuff,
> >> is how wide-sweeping the necessary API changes will be. Modifying every
> >> method, everywhere, that reparents a QObject is a little intimidating.
> >> (Maybe you have some WIP that can put this into perspective?)
> >
> > Like https://codereview.qt-project.org/c/qt/qtbase/+/260618 ?
>
> Uh... yeah, I suppose. And... yeah. Yike. That's a scary (or at least
> intimidating) amount of API churn. In particular, there are enough files
> being touched to strongly discourage me even looking at the diffs...

I don't know what to do with that. You asked whether there's a WIP,
and after being pointed to such a WIP,
you are applying a yardstick to it and then saying that you're
discouraged from even looking at it,
because it violates your arbitrary yardstick requirement. It shouldn't
come as a surprise to anyone that
adding smart pointer support to APIs that didn't have it before
requires churn, because smart pointers
don't just drop into raw pointer APIs - by design.
___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] unique_ptr and Qt, Take 2

2019-06-13 Thread Christian Ehrlicher

Am 13.06.2019 um 23:44 schrieb Konstantin Tokarev:


14.06.2019, 00:14, "Christian Ehrlicher" :

Am 13.06.2019 um 22:09 schrieb Ville Voutilainen:

  That's one of the things I love about Qt; object hierarchies give me
  working dynamic memory management without needing even smart pointers.

  That's the one thing that makes me queasy about using Qt in large
  applications; I always need
  to worry about ownership relationships, because I can't program with
  smart pointers. I had the pleasure
  of writing smart-pointer-only code 20 years ago; it was quite
  pleasant, especially considering that
  the largeish application was leaking like a sieve and doing
  use-after-free in all too many places.
  Once we plugged boost's smart pointers into it, all those problems
  went away over a weekend,
  and we never looked back.

A very good example on how to kill a library by simply using smart
pointer everywhere is QtXmlPatterns:

https://bugreports.qt.io/issues/?jql=project%20%3D%20QTBUG%20AND%20status%20%3D%20Reported%20AND%20component%20%3D%20%22XML%3A%20QtXmlPatterns%22%20ORDER%20BY%20key%20DESC

Any proffs that any of these issues were caused by smart pointers?

Otherwise I would not have mentioned it. Just take a look at the code
and one of the bug report issues... it awesome and you will see why
nobody want/can maintain this library.

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


Re: [Development] unique_ptr and Qt, Take 2

2019-06-13 Thread Konstantin Tokarev


14.06.2019, 00:14, "Christian Ehrlicher" :
> Am 13.06.2019 um 22:09 schrieb Ville Voutilainen:
>>>  That's one of the things I love about Qt; object hierarchies give me
>>>  working dynamic memory management without needing even smart pointers.
>>  That's the one thing that makes me queasy about using Qt in large
>>  applications; I always need
>>  to worry about ownership relationships, because I can't program with
>>  smart pointers. I had the pleasure
>>  of writing smart-pointer-only code 20 years ago; it was quite
>>  pleasant, especially considering that
>>  the largeish application was leaking like a sieve and doing
>>  use-after-free in all too many places.
>>  Once we plugged boost's smart pointers into it, all those problems
>>  went away over a weekend,
>>  and we never looked back.
>
> A very good example on how to kill a library by simply using smart
> pointer everywhere is QtXmlPatterns:
>
> https://bugreports.qt.io/issues/?jql=project%20%3D%20QTBUG%20AND%20status%20%3D%20Reported%20AND%20component%20%3D%20%22XML%3A%20QtXmlPatterns%22%20ORDER%20BY%20key%20DESC

Any proffs that any of these issues were caused by smart pointers?

>
> So simply saying 'smart pointer fix it all' is just wrong.

Nobody says 'fix it all', smart pointers fix only specific class of issues. 
Without smart pointers you are on your own with them too.

-- 
Regards,
Konstantin

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


Re: [Development] unique_ptr and Qt, Take 2

2019-06-13 Thread Matthew Woehlke
On 13/06/2019 16.09, Ville Voutilainen wrote:
> The minor problem being that to not so small audiences,
> new Whoosh(something);
> just looks like a bug, and then you need to look three times to
> realize that something is a parent.

Sure... but `something.createChild()` can help with that.

OTOH, I just realized a problem with that... when the new child needs to
take its parent in the ctor for other reasons. I don't know if there is
an easy solution to that. (Of course, you can still pass the parent with
createChild, but then you've violated DRY.)

>> That's one of the things I love about Qt; object hierarchies give me
>> working dynamic memory management without needing even smart pointers.
> 
> That's the one thing that makes me queasy about using Qt in large 
> applications; I always need to worry about ownership relationships,
> because I can't program with smart pointers.
I guess your mileage varies. My experience has been the opposite.

To be fair, I expect a lot of that is "instinctive"... that is, when you
come from a background where not using smart pointers is scary, the Qt
way is probably going to rub you the wrong way, even though it's nowhere
near as dangerous as your experience causes you to believe. Conversely,
being comfortable with Qt and its minimal need for smart pointers likely
produces an aversion to sprinkling them everywhere "because it's safer".

> [...] the largeish application was leaking like a sieve and doing
> use-after-free in all too many places.

QPointer is great for avoiding this :-). (Also, properly "owned"
signal/slot connections.)

> On Thu, 13 Jun 2019 at 22:54, Matthew Woehlke wrote:
>> My "concern", and possibly why everyone fixated on the unique_ptr stuff,
>> is how wide-sweeping the necessary API changes will be. Modifying every
>> method, everywhere, that reparents a QObject is a little intimidating.
>> (Maybe you have some WIP that can put this into perspective?)
> 
> Like https://codereview.qt-project.org/c/qt/qtbase/+/260618 ?

Uh... yeah, I suppose. And... yeah. Yike. That's a scary (or at least
intimidating) amount of API churn. In particular, there are enough files
being touched to strongly discourage me even looking at the diffs...

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


Re: [Development] unique_ptr and Qt, Take 2

2019-06-13 Thread Christian Ehrlicher

Am 13.06.2019 um 22:09 schrieb Ville Voutilainen:

That's one of the things I love about Qt; object hierarchies give me
working dynamic memory management without needing even smart pointers.

That's the one thing that makes me queasy about using Qt in large
applications; I always need
to worry about ownership relationships, because I can't program with
smart pointers. I had the pleasure
of writing smart-pointer-only code 20 years ago; it was quite
pleasant, especially considering that
the largeish application was leaking like a sieve and doing
use-after-free in all too many places.
Once we plugged boost's smart pointers into it, all those problems
went away over a weekend,
and we never looked back.

A very good example on how to kill a library by simply using smart
pointer everywhere is QtXmlPatterns:

https://bugreports.qt.io/issues/?jql=project%20%3D%20QTBUG%20AND%20status%20%3D%20Reported%20AND%20component%20%3D%20%22XML%3A%20QtXmlPatterns%22%20ORDER%20BY%20key%20DESC

So simply saying 'smart pointer fix it all' is just wrong.


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


Re: [Development] unique_ptr and Qt, Take 2

2019-06-13 Thread Marco Bubke
On June 13, 2019 17:25:15 Matthew Woehlke  wrote:

> On 13/06/2019 03.03, Marco Bubke wrote:
>> On June 12, 2019 23:13:14 Matthew Woehlke  wrote:
 me here. I think Daniel is on to something and we really should explore
 having smart pointers in Qt 6, but at this point I'm not convinced
 std::unique_ptr alone is it. I'd like to see what we could achieve with a
 QObject-specific smart pointer that understood ownership-taking functions
 (setParent, addWidget, etc.) and observing-only API (like connect()).
>>>
>>> Idea: make this hypothetical pointer be a QObject that initially "owns"
>>> the object to which it points. If the object is reparented, the pointer
>>> will stop "owning" it but will still have the reference.
>>
>> Can you implement it so that it fits owner? One of the purposes is that 
>> the static analysis can be sure about the ownership.
>
> I don't think so; at least, not without a lot of associated work. Part
> of the above idea is that I believe it is notionally implementable *now*
> (or even as far back as Qt4 at least). You can safely pass the raw
> pointer to methods that may or may not reparent the object, and
> everything will continue to work, but currently it isn't obvious what
> methods will or won't take ownership, and in some cases the answer to
> that question depends on additional (run-time) information. (Note in
> particular the QLayout example as mentioned elsewhere in this thread.)
But then the static analysis tool gives you many false positives. So the tool 
gets less useful. Tools get more and more important, so we want to send the 
message that "real" Qt developers don't need that tools? ;-)
___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] unique_ptr and Qt, Take 2

2019-06-13 Thread Ville Voutilainen
On Thu, 13 Jun 2019 at 22:54, Matthew Woehlke  wrote:
>
> On 13/06/2019 14.13, Daniel Teske wrote:
> > On June 12, 2019 23:13:14 Matthew Woehlke wrote:>> Generally, if you follow 
> > three rules: - If you create an object
> on the stack, either don't parent it or ensure>>   its parent outlives
> it. (Usually not hard!)>> - If you create an object with `new`,
> **create** it with a parent.>> - Otherwise use a smart pointer
> (QScopedPointer or QSharedPointer)¹. ...you just won't have
> problems.> > And that doesn't need to change with my design at all.
> To be fair, I was responding more to Giuseppe and had only briefly
> looked at the original mail. In particular, I was responding to the part
> where he quotes your example:
>
> >  QMenu menu;
> >  auto act = std::make_unique("Action!");
> >  menu.addAction(act.get());
>
> IMHO that code should never exist, and should not be encouraged. Leaving
> aside that one could use QMenu::addAction(QString) here, even in other
> cases similar to this where that would not apply, I would encourage
> following one of my first two rules instead.

The minor problem being that to not so small audiences,
new Whoosh(something);
just looks like a bug, and then you need to look three times to
realize that something is a parent.

>
> That's one of the things I love about Qt; object hierarchies give me
> working dynamic memory management without needing even smart pointers.

That's the one thing that makes me queasy about using Qt in large
applications; I always need
to worry about ownership relationships, because I can't program with
smart pointers. I had the pleasure
of writing smart-pointer-only code 20 years ago; it was quite
pleasant, especially considering that
the largeish application was leaking like a sieve and doing
use-after-free in all too many places.
Once we plugged boost's smart pointers into it, all those problems
went away over a weekend,
and we never looked back.

> > And there are small benefits that even those that don't want to use
> > unique_ptr, can get with minimal effort. For example by using the new
> > makeChild function:
> >
> > parent->makeChild(...);
>
> ...this actually seems pretty reasonable to me, especially as it only
> needs to touch the API for 1-2 classes (QObject, maybe QWidget). You're
> just providing an alternate way of following my second rule, which is
> arguably better, especially by modern C++ standards, as a) it never uses
> a bare `new`, and b) it works with QObject subclasses that have bad
> ctors that don't take a parent. (I admit I've written a few, though
> usually that is because the particular class is not expected to be heap
> allocated, or is expected to be lifetime-managed in some other manner.)

This would indeed be a great improvement, regardless of what we do
with smart pointers.

> My "concern", and possibly why everyone fixated on the unique_ptr stuff,
> is how wide-sweeping the necessary API changes will be. Modifying every
> method, everywhere, that reparents a QObject is a little intimidating.
> (Maybe you have some WIP that can put this into perspective?)

Like https://codereview.qt-project.org/c/qt/qtbase/+/260618 ?

> Adding (templated) QObject::createChild is much more approachable (and
> also conveniently dodges having anything to do with STL, which can be a
> hot-button issue on its own). I suspect if you were to pursue that
> separately, it would have a good chance of being accepted, and with many
> fewer passions inflamed in the process.

+1.
___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] unique_ptr and Qt, Take 2

2019-06-13 Thread Bernhard Lindner

> * enable templated QObjects. There's a prototype from Olivier, so is that 
> possible? 

Yes, this is long overdue.

-- 
Best Regards,
Bernhard Lindner

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


Re: [Development] unique_ptr and Qt, Take 2

2019-06-13 Thread Matthew Woehlke
On 13/06/2019 14.13, Daniel Teske wrote:
> On June 12, 2019 23:13:14 Matthew Woehlke wrote:>> Generally, if you follow 
> three rules: - If you create an object
on the stack, either don't parent it or ensure>>   its parent outlives
it. (Usually not hard!)>> - If you create an object with `new`,
**create** it with a parent.>> - Otherwise use a smart pointer
(QScopedPointer or QSharedPointer)¹. ...you just won't have
problems.> > And that doesn't need to change with my design at all.
To be fair, I was responding more to Giuseppe and had only briefly
looked at the original mail. In particular, I was responding to the part
where he quotes your example:

>  QMenu menu;
>  auto act = std::make_unique("Action!");
>  menu.addAction(act.get());

IMHO that code should never exist, and should not be encouraged. Leaving
aside that one could use QMenu::addAction(QString) here, even in other
cases similar to this where that would not apply, I would encourage
following one of my first two rules instead.

That's one of the things I love about Qt; object hierarchies give me
working dynamic memory management without needing even smart pointers.

With that out of the way, and having gone back and looked more closely
at your original post...

> To reiterate a point that seems to be a source of misunderstanding,
> in the design I proposed the vast majority of objects are never owned
> by a unique_ptr. Most objects are created with a parent.
> 
> And there are small benefits that even those that don't want to use
> unique_ptr, can get with minimal effort. For example by using the new
> makeChild function:
> 
> parent->makeChild(...);

...this actually seems pretty reasonable to me, especially as it only
needs to touch the API for 1-2 classes (QObject, maybe QWidget). You're
just providing an alternate way of following my second rule, which is
arguably better, especially by modern C++ standards, as a) it never uses
a bare `new`, and b) it works with QObject subclasses that have bad
ctors that don't take a parent. (I admit I've written a few, though
usually that is because the particular class is not expected to be heap
allocated, or is expected to be lifetime-managed in some other manner.)

Mostly what I don't want to see (and I'll freely admit this is probably
a result of others' fixation) is suddenly having to litter my Qt code
with `std::make_unique` and `std::move` all over the place for no more
lifetime safety than I've always had.

> So, I think what I have actually proposed has zero costs to those that
> don't want to use it, while enabling those that e.g. want to make use of
> tooling around memory managment capable of doing so.

My "concern", and possibly why everyone fixated on the unique_ptr stuff,
is how wide-sweeping the necessary API changes will be. Modifying every
method, everywhere, that reparents a QObject is a little intimidating.
(Maybe you have some WIP that can put this into perspective?)

Adding (templated) QObject::createChild is much more approachable (and
also conveniently dodges having anything to do with STL, which can be a
hot-button issue on its own). I suspect if you were to pursue that
separately, it would have a good chance of being accepted, and with many
fewer passions inflamed in the process.

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


Re: [Development] unique_ptr and Qt, Take 2

2019-06-13 Thread Daniel Teske

Hi,

I was happly ignoring the other threads, since I didn't like the 
temperature of some the responses.


But I guess you force me to write a response not just to you, but 
something that is a bit more general.

Or... just don't do that?

I can't recall that I've *ever* had problems with QObject ownership.


You, and a few others have made similar arguments, that start from your 
personal experience and since you do not needed something conclude that 
it is not worth doing.


And please don't read the rest of the mail as a attack on you, that's 
not intended. I think it's important to hear from all kind of different 
users, but I need to point out what I perceive as a faulty argument.


It is imho the wrong perspective:

There's a wide spectrum of Qt users.
* Some of which don't want Qt to change [much].
* Some of which want leverage new C++ features while using Qt
* Some of which want Qt to be more like the C++ standard

By arguing from a personal standpoint, you are implicitly ignoring all 
users that aren't like you. A proposal (or the rejection) should be 
based on considering the effect not just on you, but on all kind of 
different users.


Except, just considering current users, would be quite wrong.

Qt needs to continously attract new users, as it otherwise dies with the 
current user base. Those users will mostly - I would assume - come from 
a C++ backgroud. And my experience as a freelancer is that most projects 
I see use at least C++11 and I have no trouble finding projects using 
more modern standards.


But even that, would be the wrong perspective. We are discussing APIs in 
the context of Qt 6, which will be around for a decade. Thus, the 
correct perspective would be to consider which kind of user Qt wants to 
attract and serve in a few years. And I believe that in a few years, 
most people with a C++ background would expect modern apis.


The same perspective error happens from these arguing for deprecation 
and removal, too.


For example, obviously Q_FOREACH is ugly and outdated. It seems some 
argue that the benefit of not having to teach Q_FOREACH is worth the 
major pain and frustration that existing users would experience if it 
just got removed. I can't understand that.


In fact the whole premise of the thread is imho misguided. If the goal 
is making Qt and C++ more interoperable, then deprecation and removal is 
the wrong way to go about it.


The way forward should be to create win-win situations for both those 
that want to make use of modern C++ and those that are quite happy with 
Qt as it is.


For example, I wish Qt 6 would:

* enable templated QObjects. There's a prototype from Olivier, so is 
that possible?

* support move only types in Qt container
* add overloads for all functions taking bool * that make use of 
std::optional
* add overloads for all functions using output parameters. auto [...] = 
foo() is imho ugly, but that's nevertheless better than output parameters

* have great interoprability with ranges

None of that would require making Qt worse for existing users.


Generally, if you follow three rules:

- If you create an object on the stack, either don't parent it or ensure
its parent outlives it. (Usually not hard!)
- If you create an object with `new`, **create** it with a parent.
- Otherwise use a smart pointer (QScopedPointer or QSharedPointer)¹.

...you just won't have problems.


And that doesn't need to change with my design at all. You can just 
write the same code as is. To reiterate a point that seems to be a 
source of misunderstanding, in the design I proposed the vast majority 
of objects are never owned by a unique_ptr. Most objects are created 
with a parent.


And there are small benefits that even those that don't want to use 
unique_ptr, can get with minimal effort. For example by using the new 
makeChild function:


parent->makeChild(...);

It's almost impossible to forget to pass a parent parameter. And best of 
all, no one is forced to use that, but it can be adopted at whatever 
pace is best.


And for your last case of holding a QObject in a smart pointer, the 
propsal makes that drastically less akward.


So, I think what I have actually proposed has zero costs to those that 
don't want to use it, while enabling those that e.g. want to make use of 
tooling around memory managment capable of doing so.


daniel

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


Re: [Development] unique_ptr and Qt, Take 2

2019-06-13 Thread Matthew Woehlke
On 13/06/2019 03.03, Marco Bubke wrote:
> On June 12, 2019 23:13:14 Matthew Woehlke  wrote:
>>> me here. I think Daniel is on to something and we really should explore
>>> having smart pointers in Qt 6, but at this point I'm not convinced
>>> std::unique_ptr alone is it. I'd like to see what we could achieve with a
>>> QObject-specific smart pointer that understood ownership-taking functions
>>> (setParent, addWidget, etc.) and observing-only API (like connect()).
>>
>> Idea: make this hypothetical pointer be a QObject that initially "owns"
>> the object to which it points. If the object is reparented, the pointer
>> will stop "owning" it but will still have the reference.
>
> Can you implement it so that it fits owner? One of the purposes is that 
> the static analysis can be sure about the ownership.

I don't think so; at least, not without a lot of associated work. Part
of the above idea is that I believe it is notionally implementable *now*
(or even as far back as Qt4 at least). You can safely pass the raw
pointer to methods that may or may not reparent the object, and
everything will continue to work, but currently it isn't obvious what
methods will or won't take ownership, and in some cases the answer to
that question depends on additional (run-time) information. (Note in
particular the QLayout example as mentioned elsewhere in this thread.)

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


Re: [Development] unique_ptr and Qt, Take 2

2019-06-13 Thread Marco Bubke
On June 12, 2019 23:13:14 Matthew Woehlke  wrote:
>> me here. I think Daniel is on to something and we really should explore
>> having smart pointers in Qt 6, but at this point I'm not convinced
>> std::unique_ptr alone is it. I'd like to see what we could achieve with a
>> QObject-specific smart pointer that understood ownership-taking functions
>> (setParent, addWidget, etc.) and observing-only API (like connect()).
>
> Idea: make this hypothetical pointer be a QObject that initially "owns"
> the object to which it points. If the object is reparented, the pointer
> will stop "owning" it but will still have the reference.
Can you implement it so that it fits owner? One of the purposes is that the 
static analysis can be sure about the ownership.

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


Re: [Development] unique_ptr and Qt, Take 2

2019-06-12 Thread Matthew Woehlke
On 03/05/2019 15.13, Thiago Macieira wrote:
> On Friday, 3 May 2019 12:04:40 PDT Giuseppe D'Angelo via Development wrote:
>> Anyhow, I too feel that we may need a dedicated smart pointer class for
>> this, to catch all the corner cases and allow the existing flow of
>>
>> 1) create something
>> 2) (re)parent it
>> 3) keep using that something via a non-owning pointer.

Or... just don't do that?

I can't recall that I've *ever* had problems with QObject ownership.
Generally, if you follow three rules:

- If you create an object on the stack, either don't parent it or ensure
its parent outlives it. (Usually not hard!)
- If you create an object with `new`, **create** it with a parent.
- Otherwise use a smart pointer (QScopedPointer or QSharedPointer)¹.

...you just won't have problems.

(¹ These days, you can also add "or STL equivalents".)

> Same here. I think Daniel is on to something and we really should explore 
> having smart pointers in Qt 6, but at this point I'm not convinced 
> std::unique_ptr alone is it. I'd like to see what we could achieve with a 
> QObject-specific smart pointer that understood ownership-taking functions 
> (setParent, addWidget, etc.) and observing-only API (like connect()).

Idea: make this hypothetical pointer be a QObject that initially "owns"
the object to which it points. If the object is reparented, the pointer
will stop "owning" it but will still have the reference.

(Not an optimal implementation, but could be easily implemented as a
proof of concept.)

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


Re: [Development] unique_ptr and Qt, Take 2

2019-05-08 Thread Daniel Teske


The patch I propose does not take that into account and is indeed 
almost entirely source compatible.



Scratch the "not".


And while I'd encourage someone to try it out, I'm of the firm opinion 
that Qt should try to get over its NIH attitude. One of the issues 
with Qt in the real world is that it's just that tiny bit differently 
than what non Qt C++ users are familiar with for. Sometimes that's for 
a good reason. but there's a cost there that is imho unappreciated 
inside the Qt bubble.


That sounds a bit harsher than intended and I should expand a bit on the 
costs:


* Non Qt C++ developers can be expected to be familiar with how 
unique_ptr works. Today that might not be a entirely true, but we aren't 
deciding the api for today. We are deciding on the api for the next years.


* Static analyzers understand standard c++ but are unlikely to 
understand the Qt dialect. [1]


* Using standard c++ means, that any evolution in c++ benefits Qt 
automatically.


daniel

[1] For another example, clang-tidy knows about standard smart pointers 
for its use after move check: 
https://clang.llvm.org/extra/clang-tidy/checks/bugprone-use-after-move.html


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


Re: [Development] unique_ptr and Qt, Take 2

2019-05-07 Thread Daniel Teske


Am 06.05.2019 um 12:04 schrieb Lars Knoll:


On 6 May 2019, at 10:27, Konstantin Shegunov > wrote:


On Mon, May 6, 2019 at 10:42 AM Lars Knoll > wrote:


Not sure whether it’s most projects, but there certainly are
users doing it. And we’ve been using the pattern in our examples
in some cases as well. But I can relate to Allan that creating
widgets on the stack is bad style (as it conflicts with the way
we memory manage them), and if I’d have a choice today, I would
probably prefer to enforce them to be created on the heap by some
means.


Fine, there seems to be somewhat of an argument in that regard. I'd 
raise the question then, what should be done for QObject derived 
classes, and I don't mean the ones that come from Qt (i.e. QFile, 
which Thiago mentioned), but the ones the user defines. In the end 
QObject is for us to derive from - get signals and slots and all 
those goodies. But then if one restricts QObject to be on the heap 
how do we treat the user classes? What I mean is - you can control 
how allocations happen in the library, say you provide custom 
new/delete for QObject and/or QWidget and restrict the stack 
(presumably through some trickery that disables the constructor), 
does this mean we are to force the user to write their own allocation 
operators for their classes? This doesn't really sound practical to 
say the least. Moreover there's really little reason (from the user's 
point of view) to have something in the heap if it can go on the 
stack. What do we do with QCoreApplicaiton, force the heap on it?


It’s somewhat of a philosophical discussion now, as we are where we 
are and users can and are creating QObject’s on the stack. I don’t 
think we can change that now (even for Qt 6), and restricting it would 
lead to rather ugly syntax in C++ (as the language doesn’t really help 
enforcing something like this). So that means we’ll have to continue 
to support it.


That's something that needs to be taken into account in any change in 
how memory management could work in Qt6. The patch I propose does not 
take that into account and is indeed almost entirely source compatible. 
(No changes in Qt Creator required, and two minor changes in tests.)


And the constructors/apis that are marked with QT_UNSAFE_API by default 
don't even emit any warning. The user can opt into those warnings.


One thing I forgot to mention, which is something I only have a mediocre 
solution for is, modal QDialogs (or any other top level widgets) on the 
stack. For those the parent pointer is both the owner and indicates to 
which parent the dialog is modal. In my opinion, the best solution is to 
disentangle this. E.g. introduce a new method ::setModalTo(QWidget *), 
which if used overwrites to which parent a dialog is modal. (That is by 
default a dialog is modal to its parent, unless something else is set 
via setModalTo). This means code that uses modal widgets on the stack 
would need some conversion work, but that's as far as I can see the best 
solution.



The main benefits I see here that this scheme can co-exist with current
code, i.e. code bases could slowly opt-in and migrate step by step, and
it does not add the need to sprinkle user side code with the typical
smart pointer line noise.
The same is true for what I'm proposing. It can and does allow users to 
convert at they choosing, and since the vast majority of QObjects are 
created with parents, most QObjects will be created via makeChild. Using 
unique pointers is the exception not the norm with what I've proposed. 
And indeed due to the ergonomics of makeChild via make_unique, the user 
is steared towards using the better way to construct QObjects.


Now, what André is proposing is very similar to just having a owning 
smart pointer that remembers the pointed at object after it has lost 
ownership. I see no reason why that (or more fuller proxy classes) 
couldn't work. But,


* The class/smart pointer would need to be move only, which limits how 
useful it is.

* The semantics feel strange to me.

And while I'd encourage someone to try it out, I'm of the firm opinion 
that Qt should try to get over its NIH attitude. One of the issues with 
Qt in the real world is that it's just that tiny bit differently than 
what non Qt C++ users are familiar with for. Sometimes that's for a good 
reason. but there's a cost there that is imho unappreciated inside the 
Qt bubble.


Also nowadays C++ is changing quite fast and the way to profit from the 
advancements in standard c++ is by making sure that Qt works great with 
new standard c++ idioms. It's not by investing time into inventing a 
slightly different idiom.


For example, Microsoft is still researching whether static analysers 
could detect dangling pointers [2]. That tool obviously will understand 
unique_ptr and is unlikely to understand our custom solution.


daniel

[1] 

Re: [Development] unique_ptr and Qt, Take 2

2019-05-07 Thread Konstantin Tokarev

>> Can you explain what you mean with “understands the parent/child-ownership 
>> model”?
>>
>> Are you suggesting a unique_ptr-like template class that doesn’t destroy the 
>> object in its destructor if that object still has a parent?
>
> It could be something like that. One option could be to behave like a 
> unique_ptr if the object doesn’t have a parent, and like a weak pointer 
> otherwise. One would have to try it out though, to see whether that would 
> give semantics that are intuitive and feel right to users.

Intuitive behavior would be to behave like weak pointer if object has a parent 
and is a direct class member of its parent object, otherwise behave like a 
unique_ptr.


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


Re: [Development] unique_ptr and Qt, Take 2

2019-05-07 Thread Lars Knoll


On 7 May 2019, at 15:00, Volker Hilsheimer 
mailto:volker.hilshei...@qt.io>> wrote:

On 6 May 2019, at 22:20, Lars Knoll mailto:lars.kn...@qt.io>> 
wrote:
On 6 May 2019, at 20:23, André Pönitz 
mailto:apoen...@t-online.de>> wrote:

On Mon, May 06, 2019 at 07:41:05AM +, Lars Knoll wrote:
On 6 May 2019, at 09:30, Christian Kandeler
mailto:christian.kande...@qt.io>> wrote:

On Sat, 04 May 2019 09:06:39 +0200 Allan Sandfeld Jensen
mailto:k...@carewolf.com>> wrote:

On Samstag, 4. Mai 2019 00:43:10 CEST Thiago Macieira wrote:
On Friday, 3 May 2019 13:00:52 PDT Иван Комиссаров wrote:
Which should be considered bad practice and banned on an API
level

No way.

Are you going to forbid creation of QFile on the stack?

Perhaps QFile shouldn't be the same kind of base object type as
QWidgets? Or not use the same smart pointer.

Though even making QWidgets not allowed on the stack, while
sensible, would break a many of our tests, where we "abuse" that it
is technically possible in simple cases.

Doesn't almost every project create its main widget on the stack?

Not sure whether it’s most projects, but there certainly are users
doing it. And we’ve been using the pattern in our examples in some
cases as well. But I can relate to Allan that creating widgets on the
stack is bad style (as it conflicts with the way we memory manage
them), and if I’d have a choice today, I would probably prefer to
enforce them to be created on the heap by some means.

I wonder whether there's a solution in the following direction:

Have something like the following for each QObject derived class Foo
(for which it makes sense. E.g. perhaps all widgets, but not QFile):

[…]

The main benefits I see here that this scheme can co-exist with current
code, i.e. code bases could slowly opt-in and migrate step by step, and
it does not add the need to sprinkle user side code with the typical
smart pointer line noise.

Interesting idea. I sometimes thought that if we’d be creating Qt from scratch, 
one could make it all value based and have the objects on the heap hidden 
behind it. This would give something similar. As an added benefit, we could 
probably allocate the object and it’s private in one go without requiring the 
TLS hacks that https://codereview.qt-project.org/#/c/165445/ uses.

This could maybe bet combined with a custom template class handling our 
pointers (instead of unique_ptr) that understands the parent/child ownership 
model, plus typedefs for the different QObject based classes in the Qt 
namespace.


Can you explain what you mean with “understands the parent/child-ownership 
model”?

Are you suggesting a unique_ptr-like template class that doesn’t destroy the 
object in its destructor if that object still has a parent?

It could be something like that. One option could be to behave like a 
unique_ptr if the object doesn’t have a parent, and like a weak pointer 
otherwise. One would have to try it out though, to see whether that would give 
semantics that are intuitive and feel right to users.

Cheers,
Lars



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


Re: [Development] unique_ptr and Qt, Take 2

2019-05-07 Thread Volker Hilsheimer
On 6 May 2019, at 22:20, Lars Knoll mailto:lars.kn...@qt.io>> 
wrote:
On 6 May 2019, at 20:23, André Pönitz 
mailto:apoen...@t-online.de>> wrote:

On Mon, May 06, 2019 at 07:41:05AM +, Lars Knoll wrote:
On 6 May 2019, at 09:30, Christian Kandeler
mailto:christian.kande...@qt.io>> wrote:

On Sat, 04 May 2019 09:06:39 +0200 Allan Sandfeld Jensen
mailto:k...@carewolf.com>> wrote:

On Samstag, 4. Mai 2019 00:43:10 CEST Thiago Macieira wrote:
On Friday, 3 May 2019 13:00:52 PDT Иван Комиссаров wrote:
Which should be considered bad practice and banned on an API
level

No way.

Are you going to forbid creation of QFile on the stack?

Perhaps QFile shouldn't be the same kind of base object type as
QWidgets? Or not use the same smart pointer.

Though even making QWidgets not allowed on the stack, while
sensible, would break a many of our tests, where we "abuse" that it
is technically possible in simple cases.

Doesn't almost every project create its main widget on the stack?

Not sure whether it’s most projects, but there certainly are users
doing it. And we’ve been using the pattern in our examples in some
cases as well. But I can relate to Allan that creating widgets on the
stack is bad style (as it conflicts with the way we memory manage
them), and if I’d have a choice today, I would probably prefer to
enforce them to be created on the heap by some means.

I wonder whether there's a solution in the following direction:

Have something like the following for each QObject derived class Foo
(for which it makes sense. E.g. perhaps all widgets, but not QFile):

[…]

The main benefits I see here that this scheme can co-exist with current
code, i.e. code bases could slowly opt-in and migrate step by step, and
it does not add the need to sprinkle user side code with the typical
smart pointer line noise.

Interesting idea. I sometimes thought that if we’d be creating Qt from scratch, 
one could make it all value based and have the objects on the heap hidden 
behind it. This would give something similar. As an added benefit, we could 
probably allocate the object and it’s private in one go without requiring the 
TLS hacks that https://codereview.qt-project.org/#/c/165445/ uses.

This could maybe bet combined with a custom template class handling our 
pointers (instead of unique_ptr) that understands the parent/child ownership 
model, plus typedefs for the different QObject based classes in the Qt 
namespace.


Can you explain what you mean with “understands the parent/child-ownership 
model”?

Are you suggesting a unique_ptr-like template class that doesn’t destroy the 
object in its destructor if that object still has a parent?


Volker

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


Re: [Development] unique_ptr and Qt, Take 2

2019-05-06 Thread Lars Knoll


On 6 May 2019, at 20:23, André Pönitz 
mailto:apoen...@t-online.de>> wrote:

On Mon, May 06, 2019 at 07:41:05AM +, Lars Knoll wrote:
On 6 May 2019, at 09:30, Christian Kandeler
mailto:christian.kande...@qt.io>> wrote:

On Sat, 04 May 2019 09:06:39 +0200 Allan Sandfeld Jensen
mailto:k...@carewolf.com>> wrote:

On Samstag, 4. Mai 2019 00:43:10 CEST Thiago Macieira wrote:
On Friday, 3 May 2019 13:00:52 PDT Иван Комиссаров wrote:
Which should be considered bad practice and banned on an API
level

No way.

Are you going to forbid creation of QFile on the stack?

Perhaps QFile shouldn't be the same kind of base object type as
QWidgets? Or not use the same smart pointer.

Though even making QWidgets not allowed on the stack, while
sensible, would break a many of our tests, where we "abuse" that it
is technically possible in simple cases.

Doesn't almost every project create its main widget on the stack?

Not sure whether it’s most projects, but there certainly are users
doing it. And we’ve been using the pattern in our examples in some
cases as well. But I can relate to Allan that creating widgets on the
stack is bad style (as it conflicts with the way we memory manage
them), and if I’d have a choice today, I would probably prefer to
enforce them to be created on the heap by some means.

I wonder whether there's a solution in the following direction:

Have something like the following for each QObject derived class Foo
(for which it makes sense. E.g. perhaps all widgets, but not QFile):

namespace Qt {

class Foo
{
public:
  Foo() : p(new QFoo), owning(true) {}
   // more ctors forwarding to QFoo ctor

  ~Foo() { if (owning) delete p; }

   // make  movable but not copiable...

  // forward QFoo interface to p->

private:
  QPointer p;  // Maybe QFoo *p.
  bool owning;  // Perhaps somehow mangled into p
  ...
  // whatever else is needed. Shouldn't be much.
};

} // namespace Qt

Those things could be 'stack only', and be reasonably explicit
about ownership without being too much of a pain to use.

Example code could be sth like:

int main(...)
{
  // a will own its a.p, and will destroy it when w itself dies.
  Application a(...);

  // w will own its w.p, and will destroy it when w itself dies.
  MainWindow w;

  // addChild would forward to QFoo's constructor and set 'owning'
  // to false on the resulting Foo, i.e. l is now known to be owned
  //  by something else, and will not destroy l.p in its dtor
  // w takes ownership of l, e.g. using the classic QObject
  // parent/child mechanisme on w.p and l.p. Or something else.
  Label l = w.addChild("Something");

  l.setSomething(..,); // call l.p->setSomething(...)

  w.show();  // call w.p->show()

  return a.exec(); // call a.p->show()

  // l will be destroyed, but not l.p as l.owning == false
  // w will be destroyed including w.p, and trigger the
  //   destruction of QItems created/owned by it, e.g. l.p
  // a will be destroyed including a.p
}

The main benefits I see here that this scheme can co-exist with current
code, i.e. code bases could slowly opt-in and migrate step by step, and
it does not add the need to sprinkle user side code with the typical
smart pointer line noise.

Interesting idea. I sometimes thought that if we’d be creating Qt from scratch, 
one could make it all value based and have the objects on the heap hidden 
behind it. This would give something similar. As an added benefit, we could 
probably allocate the object and it’s private in one go without requiring the 
TLS hacks that https://codereview.qt-project.org/#/c/165445/ uses.

This could maybe bet combined with a custom template class handling our 
pointers (instead of unique_ptr) that understands the parent/child ownership 
model, plus typedefs for the different QObject based classes in the Qt 
namespace.

Cheers,
Lars


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


Re: [Development] unique_ptr and Qt, Take 2

2019-05-06 Thread André Pönitz
On Mon, May 06, 2019 at 07:41:05AM +, Lars Knoll wrote:
> > On 6 May 2019, at 09:30, Christian Kandeler
> >  wrote:
> > 
> > On Sat, 04 May 2019 09:06:39 +0200 Allan Sandfeld Jensen
> >  wrote:
> > 
> >> On Samstag, 4. Mai 2019 00:43:10 CEST Thiago Macieira wrote:
> >>> On Friday, 3 May 2019 13:00:52 PDT Иван Комиссаров wrote:
>  Which should be considered bad practice and banned on an API
>  level
> >>> 
> >>> No way.
> >>> 
> >>> Are you going to forbid creation of QFile on the stack?
> >> 
> >> Perhaps QFile shouldn't be the same kind of base object type as
> >> QWidgets? Or not use the same smart pointer.
> >> 
> >> Though even making QWidgets not allowed on the stack, while
> >> sensible, would break a many of our tests, where we "abuse" that it
> >> is technically possible in simple cases.
> > 
> > Doesn't almost every project create its main widget on the stack? 
> 
> Not sure whether it’s most projects, but there certainly are users
> doing it. And we’ve been using the pattern in our examples in some
> cases as well. But I can relate to Allan that creating widgets on the
> stack is bad style (as it conflicts with the way we memory manage
> them), and if I’d have a choice today, I would probably prefer to
> enforce them to be created on the heap by some means.

I wonder whether there's a solution in the following direction:

Have something like the following for each QObject derived class Foo
(for which it makes sense. E.g. perhaps all widgets, but not QFile):

namespace Qt {

class Foo 
{
public:
   Foo() : p(new QFoo), owning(true) {} 
// more ctors forwarding to QFoo ctor

   ~Foo() { if (owning) delete p; }

// make  movable but not copiable...

   // forward QFoo interface to p->

private:
   QPointer p;  // Maybe QFoo *p.
   bool owning;  // Perhaps somehow mangled into p
   ...
   // whatever else is needed. Shouldn't be much.
};

} // namespace Qt

Those things could be 'stack only', and be reasonably explicit
about ownership without being too much of a pain to use.

Example code could be sth like:

int main(...)
{
   // a will own its a.p, and will destroy it when w itself dies.
   Application a(...);

   // w will own its w.p, and will destroy it when w itself dies.
   MainWindow w;

   // addChild would forward to QFoo's constructor and set 'owning'
   // to false on the resulting Foo, i.e. l is now known to be owned
   //  by something else, and will not destroy l.p in its dtor
   // w takes ownership of l, e.g. using the classic QObject
   // parent/child mechanisme on w.p and l.p. Or something else.
   Label l = w.addChild("Something"); 

   l.setSomething(..,); // call l.p->setSomething(...)

   w.show();  // call w.p->show()

   return a.exec(); // call a.p->show()

   // l will be destroyed, but not l.p as l.owning == false
   // w will be destroyed including w.p, and trigger the
   //   destruction of QItems created/owned by it, e.g. l.p 
   // a will be destroyed including a.p
}

The main benefits I see here that this scheme can co-exist with current
code, i.e. code bases could slowly opt-in and migrate step by step, and
it does not add the need to sprinkle user side code with the typical
smart pointer line noise.

Andre'
___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] unique_ptr and Qt, Take 2

2019-05-06 Thread Vitaly Fanaskov
Well, it should be possible, to support parents, created on the stack. We 
already have the code to do it. The code is private, unfortunately, but it 
doesn't matter. In the following file:

qtbase/src/corelib/tools/qsharedpointer_impl.h

We have the following constructor, used by QPointer:

template  inline QWeakPointer(X *ptr, bool) : d(ptr ? 
Data::getAndRef(ptr) : nullptr), value(ptr) { }

That's it. We can use it for both case. There are some changes in QObject 
interface:

QObject(QWeakPointer parent = {})

// Use casting operator instead?

QWeakPointer asWeakRef() { return {this, true}; } QWeakPointer asWeakRef() const { return {this, true}; } QWeakPointer 
parent;

And some usage examples:

 auto o1 = QSharedPointer(new QObject);

auto o2 = new QObject(o1);

// Or...



QObject o1;

QObject o2(o1.asWeakRef());

I compiled and tested after patching Qt, works fine. Of course, I didn't 
implement full functionality, just a shallow example. QWeakPointer also 
gracefully handles the case if a user tries to invoke something like 
toStrongRef() in the second example. Some reasonable warning will be put to the 
terminal and an empty QSharedPointer returned.

This also means that we will have to use our own smart pointers everywhere in 
the interface (for consistency). We will also have to change some things (e.g., 
make QScopePointer movable), but this is the matter of another discussion. 
Which is not bad, because it'll help to avoid some well-known problems of using 
std::* in library interfaces, along with memory allocation/cleaning issues. And 
again, this is much better than having raw pointers.

On 5/6/19 12:04 PM, Lars Knoll wrote:

On 6 May 2019, at 10:27, Konstantin Shegunov 
mailto:kshegu...@gmail.com>> wrote:

On Mon, May 6, 2019 at 10:42 AM Lars Knoll 
mailto:lars.kn...@qt.io>> wrote:
Not sure whether it’s most projects, but there certainly are users doing it. 
And we’ve been using the pattern in our examples in some cases as well. But I 
can relate to Allan that creating widgets on the stack is bad style (as it 
conflicts with the way we memory manage them), and if I’d have a choice today, 
I would probably prefer to enforce them to be created on the heap by some means.

Fine, there seems to be somewhat of an argument in that regard. I'd raise the 
question then, what should be done for QObject derived classes, and I don't 
mean the ones that come from Qt (i.e. QFile, which Thiago mentioned), but the 
ones the user defines. In the end QObject is for us to derive from - get 
signals and slots and all those goodies. But then if one restricts QObject to 
be on the heap how do we treat the user classes? What I mean is - you can 
control how allocations happen in the library, say you provide custom 
new/delete for QObject and/or QWidget and restrict the stack (presumably 
through some trickery that disables the constructor), does this mean we are to 
force the user to write their own allocation operators for their classes? This 
doesn't really sound practical to say the least. Moreover there's really little 
reason (from the user's point of view) to have something in the heap if it can 
go on the stack. What do we do with QCoreApplicaiton, force the heap on it?

It’s somewhat of a philosophical discussion now, as we are where we are and 
users can and are creating QObject’s on the stack. I don’t think we can change 
that now (even for Qt 6), and restricting it would lead to rather ugly syntax 
in C++ (as the language doesn’t really help enforcing something like this). So 
that means we’ll have to continue to support it.

Cheers,
Lars




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


--
Best Regards,

Fanaskov Vitaly
Senior Software Engineer

The Qt Company / Qt Quick and Widgets Team
___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] unique_ptr and Qt, Take 2

2019-05-06 Thread Lars Knoll

On 6 May 2019, at 10:27, Konstantin Shegunov 
mailto:kshegu...@gmail.com>> wrote:

On Mon, May 6, 2019 at 10:42 AM Lars Knoll 
mailto:lars.kn...@qt.io>> wrote:
Not sure whether it’s most projects, but there certainly are users doing it. 
And we’ve been using the pattern in our examples in some cases as well. But I 
can relate to Allan that creating widgets on the stack is bad style (as it 
conflicts with the way we memory manage them), and if I’d have a choice today, 
I would probably prefer to enforce them to be created on the heap by some means.

Fine, there seems to be somewhat of an argument in that regard. I'd raise the 
question then, what should be done for QObject derived classes, and I don't 
mean the ones that come from Qt (i.e. QFile, which Thiago mentioned), but the 
ones the user defines. In the end QObject is for us to derive from - get 
signals and slots and all those goodies. But then if one restricts QObject to 
be on the heap how do we treat the user classes? What I mean is - you can 
control how allocations happen in the library, say you provide custom 
new/delete for QObject and/or QWidget and restrict the stack (presumably 
through some trickery that disables the constructor), does this mean we are to 
force the user to write their own allocation operators for their classes? This 
doesn't really sound practical to say the least. Moreover there's really little 
reason (from the user's point of view) to have something in the heap if it can 
go on the stack. What do we do with QCoreApplicaiton, force the heap on it?

It’s somewhat of a philosophical discussion now, as we are where we are and 
users can and are creating QObject’s on the stack. I don’t think we can change 
that now (even for Qt 6), and restricting it would lead to rather ugly syntax 
in C++ (as the language doesn’t really help enforcing something like this). So 
that means we’ll have to continue to support it.

Cheers,
Lars

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


Re: [Development] unique_ptr and Qt, Take 2

2019-05-06 Thread Konstantin Shegunov
On Mon, May 6, 2019 at 10:42 AM Lars Knoll  wrote:

> Not sure whether it’s most projects, but there certainly are users doing
> it. And we’ve been using the pattern in our examples in some cases as well.
> But I can relate to Allan that creating widgets on the stack is bad style
> (as it conflicts with the way we memory manage them), and if I’d have a
> choice today, I would probably prefer to enforce them to be created on the
> heap by some means.
>

Fine, there seems to be somewhat of an argument in that regard. I'd raise
the question then, what should be done for QObject derived classes, and I
don't mean the ones that come from Qt (i.e. QFile, which Thiago mentioned),
but the ones the user defines. In the end QObject is for us to derive from
- get signals and slots and all those goodies. But then if one restricts
QObject to be on the heap how do we treat the user classes? What I mean is
- you can control how allocations happen in the library, say you provide
custom new/delete for QObject and/or QWidget and restrict the stack
(presumably through some trickery that disables the constructor), does this
mean we are to force the user to write their own allocation operators for
their classes? This doesn't really sound practical to say the least.
Moreover there's really little reason (from the user's point of view) to
have something in the heap if it can go on the stack. What do we do with
QCoreApplicaiton, force the heap on it?
___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] unique_ptr and Qt, Take 2

2019-05-06 Thread Lars Knoll
> On 6 May 2019, at 09:30, Christian Kandeler  wrote:
> 
> On Sat, 04 May 2019 09:06:39 +0200
> Allan Sandfeld Jensen  wrote:
> 
>> On Samstag, 4. Mai 2019 00:43:10 CEST Thiago Macieira wrote:
>>> On Friday, 3 May 2019 13:00:52 PDT Иван Комиссаров wrote:
 Which should be considered bad practice and banned on an API level
>>> 
>>> No way.
>>> 
>>> Are you going to forbid creation of QFile on the stack?
>> 
>> Perhaps QFile shouldn't be the same kind of base object type as QWidgets? Or 
>> not use the same smart pointer.
>> 
>> Though even making QWidgets not allowed on the stack, while sensible, would 
>> break a many of our tests, where we "abuse" that it is technically possible 
>> in 
>> simple cases.
> 
> Doesn't almost every project create its main widget on the stack? 

Not sure whether it’s most projects, but there certainly are users doing it. 
And we’ve been using the pattern in our examples in some cases as well. But I 
can relate to Allan that creating widgets on the stack is bad style (as it 
conflicts with the way we memory manage them), and if I’d have a choice today, 
I would probably prefer to enforce them to be created on the heap by some means.

Cheers,
Lars



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


Re: [Development] unique_ptr and Qt, Take 2

2019-05-06 Thread Иван Комиссаров
True, but it’s ownership is never transferred, so it’s out of the scope of 
discussion - user is free to use any c++ idiom he likes.
I would like to discuss how to transfer ownership in modern Qt.

> 6 мая 2019 г., в 9:30, Christian Kandeler  
> написал(а):
> 
> On Sat, 04 May 2019 09:06:39 +0200
> Allan Sandfeld Jensen  wrote:
> 
>> On Samstag, 4. Mai 2019 00:43:10 CEST Thiago Macieira wrote:
>>> On Friday, 3 May 2019 13:00:52 PDT Иван Комиссаров wrote:
 Which should be considered bad practice and banned on an API level
>>> 
>>> No way.
>>> 
>>> Are you going to forbid creation of QFile on the stack?
>> 
>> Perhaps QFile shouldn't be the same kind of base object type as QWidgets? Or 
>> not use the same smart pointer.
>> 
>> Though even making QWidgets not allowed on the stack, while sensible, would 
>> break a many of our tests, where we "abuse" that it is technically possible 
>> in 
>> simple cases.
> 
> Doesn't almost every project create its main widget on the stack? 
> 
> 
> Christian
> ___
> 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] unique_ptr and Qt, Take 2

2019-05-06 Thread Christian Kandeler
On Sat, 04 May 2019 09:06:39 +0200
Allan Sandfeld Jensen  wrote:

> On Samstag, 4. Mai 2019 00:43:10 CEST Thiago Macieira wrote:
> > On Friday, 3 May 2019 13:00:52 PDT Иван Комиссаров wrote:
> > > Which should be considered bad practice and banned on an API level
> > 
> > No way.
> > 
> > Are you going to forbid creation of QFile on the stack?
> 
> Perhaps QFile shouldn't be the same kind of base object type as QWidgets? Or 
> not use the same smart pointer.
> 
> Though even making QWidgets not allowed on the stack, while sensible, would 
> break a many of our tests, where we "abuse" that it is technically possible 
> in 
> simple cases.

Doesn't almost every project create its main widget on the stack? 


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


Re: [Development] unique_ptr and Qt, Take 2

2019-05-04 Thread Иван Комиссаров
That’s exactly the problem we’re discussing here.

Consider this example (was writing without a compiler, might be typos)
class MyWidget : public QWidget
{
QWidget container; // note, doesn’t require explicit parent, layout handles 
that
QLabel label;
public:
Widget(QWidget *parent) : QWidget(parent), childWidget()
{
   auto layout = new QMyLayout(this);
   layout->addWidget(); // is ownership transferred here?
   label.setText(«Hello»);
}
};

Who owns label? Is the ownership truly unique here? Is it shared? It’s 
something in-between - container thinks that it owns a label but in fact it 
does not, the real owner is MyWidget.

Note, that this worked for ages and people are using this idiom to save one 
extra allocation, plus it requires less typing. And this is intuitive. But that 
doesn’t exactly the «QObject deletes his children» idiom.

Maybe we need something like «maybe owner pointer» which has a ptr to an object 
and bool if it should delete it or not. This pointer can be constructed from 
reference (aka «on a stack») with own=false. However, the semantics and the API 
of such pointer is not clear for me, it’s easy to end up with another auto_ptr, 
so confider this as a crazy idea.

> 4 мая 2019 г., в 0:36, Giuseppe D'Angelo  
> написал(а):
> 
> Il 04/05/19 00:33, Иван Комиссаров ha scritto:
>> Back to the topic - in case we really want to support the "stack case", I’d 
>> say shared_ptr is the only option (in combination with 
>> enable_shared_from_this which is already a kinda part of QObject, as 
>> mentioned above)
> 
> QObject ownership isn't shared, it's unique. A widget is in ONE hierarchy, 
> which fixes its owning native window, its coordinate system, its Z order 
> amongst its siblings; not N hierarchies.
> 
> -- 
> 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
> 

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


Re: [Development] unique_ptr and Qt, Take 2

2019-05-04 Thread Allan Sandfeld Jensen
On Samstag, 4. Mai 2019 00:43:10 CEST Thiago Macieira wrote:
> On Friday, 3 May 2019 13:00:52 PDT Иван Комиссаров wrote:
> > Which should be considered bad practice and banned on an API level
> 
> No way.
> 
> Are you going to forbid creation of QFile on the stack?

Perhaps QFile shouldn't be the same kind of base object type as QWidgets? Or 
not use the same smart pointer.

Though even making QWidgets not allowed on the stack, while sensible, would 
break a many of our tests, where we "abuse" that it is technically possible in 
simple cases.

'Allan


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


Re: [Development] unique_ptr and Qt, Take 2

2019-05-04 Thread Daniel Teske


Иван Комиссаров:

IMHO, it should be a Qt6 feature. It’s awesome.

However, I liked the idea (is it deprecated or what?) of a template 
method

template
std::observer_ptr 
qMakeChild(gsll::not_null> parent, Args… args)

{
    return parent->adoptChild(std::make_unique(args));
}


For some classes, notably QLayout constructing with a parent is 
different from setting a parent later. The former automatically sets the 
layout, whereas the later doesn't.


So, what you would need to do is in pseudo code:

std::observer_ptr 
qMakeChild(gsll::not_null> parent, Args… args)

{
 auto obj = std::make_unique(args);
 if hasMember(T:initWithParent)
 obj->initWithParent(parent)
    return parent->adoptChild(std::move(obj));
}

And obviously create a initWithParent method on all classes that are 
special like QLayout. I didn't explore that, as it didn't feel that nice 
to me





Maybe I’m asking too much, but it would be nice get rid of raw 
pointers completely switching to pair std::unique_ptr/std::observer_ptr


I don't think observer_ptr has only miniscule benefit over a raw pointer 
and I think it's ugly.


Thiago Macieira:

On Friday, 3 May 2019 10:22:20 PDT Daniel Teske wrote:

std::unique_ptr rightButton =
std::make_unique("RIGHT");
layout->addWidget(std::move(rightButton));
The problem in this particular example is that once you've added the 
widget,
the rightButton smart pointer no longer has a pointer. You can't 
continue to
set up your push button. In most cases, this is just a matter of 
moving the
set up before the addition / reparenting, or using the other idiom 
where the

object is never in a smart pointer in the first place.

So this begs the question of whether std::unique_ptr is the best smart 
pointer
for this scenario. Would it make sense to create one that understands 
parent-

child relationship?


addWidget could return a raw pointer to he widget, also that would 
require making addWidget and a bunch of other functions templates.


(They need to be templates, because we want to return the subclass that 
is stored in the unique_ptr, that is: T * addWidget(std::unique_ptr) 
is the right signature.)


But, on the topic of using our own smart pointer class.

I think unique_ptr actually works well enough with Qt's parent/child 
relationship with the right apis, because both use similar enough concepts.


Using the standards mechanism for memory management has the benefit that 
it is well-known outside the Qt world and aligns Qt better with modern 
practices, whereas our own smart pointer is again our own very different 
corner of C++.


I think that standard C++ is developing quite rapidly and for Qt's to 
profit from that development it needs to try harder to adopt changes in 
C++. And I believe that to be critical to Qt's long term success.


std::unique_ptr rightButton = 
std::make_unique("RIGHT");
layout->addWidget(std::move(rightButton)); 


To really, really, really nitpick, this last line is (or feels) wrong: 
layouts do not take ownership of the widgets they manage. An ownership 
transfer MAY happen immediately (if the layout is installed) or later 
(as soon as the layout is installed). 
I actually didn't know that and must have missed it. ( There are 
obviously lots of apis, I did check the documentation and read the 
implementation of most functions, but it's rather likely that a bunch of 
my implementations miss subtle details.)


So, what the function should do is to always do take ownership and if 
that requires behaving a bit differently than addWidget, so be it.


For example one case where I did catch something like that, the two 
variants of QAbstractItemView::setIndexWidgetbehave slightly differently.


* If the model index is valid, both take ownership of the widget.
* If the model index is invalid
    * The normal version does nothing
    * The unique_ptr version deletes the widget

Now, I'm in a bit of a hurry atm, but QLayout basically would need to 
ensure that any unique_ptrs that it took ownership of are either passed 
on to its parent widget, or are deleted in ~QLayout.


daniel

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


Re: [Development] unique_ptr and Qt, Take 2

2019-05-03 Thread Konstantin Ritt
what about the other corner case:

`
~Some() {
const auto children = someChildren();
for (auto child : children) {
if (!child->isDepleted()) {
// 'detach' and let it die alone, some later...
child->setParent(nullptr);
QObject::connect(child, ::depleted, child,
::deleteLater);
// f.i. child on a secondary thread couldn't be parented by qApp
QObject::connect(qApp, ::aboutToQuit, child,
::deleteLater);
} else {
delete child;
}
}
}
`

?

I bet that isn't that simple to do with just unique_ptr (or any other
std::_ptr). Is it?


As for beforementioned QLayout and QAction examples, sure the API could be
improved to make re-parenting obvious and to avoid resources leakage, etc.
However, unique_ptr isn't that holly bullet to solve the lazy programmer's
issues. IMO.


Konstantin

сб, 4 мая 2019 г., 2:34 Thiago Macieira :

> On Friday, 3 May 2019 16:14:09 PDT Иван Комиссаров wrote:
> > What I am talking about is that explicit is better than implicit. Taking
> an
> > address of an object on a stack and passing it to a function that
> (possibly
> > can) delete your object is not explicit. Wrapping that operation in a
> > construction of a smart pointer is explicit. Moving a unique_ptr is
> > explicit. When you’re «casting» your on-a-stack-QFile to a some smart
> > pointer, you’re telling the compiler (and other people who read the code)
> > «trust me, I know what I’m doing, this is intended».
>
> That I can agree with, but this goes back to the suggestion of our own
> smart
> QObject pointer classes. In non-compatibility mode, a function that adopts
> the
> passed object should only accept from another smart pointer. If you pass a
> naked pointer, it should reject and force you to clearly state that you
> know
> what you're doing.
>
> --
> 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] unique_ptr and Qt, Take 2

2019-05-03 Thread Thiago Macieira
On Friday, 3 May 2019 16:14:09 PDT Иван Комиссаров wrote:
> What I am talking about is that explicit is better than implicit. Taking an
> address of an object on a stack and passing it to a function that (possibly
> can) delete your object is not explicit. Wrapping that operation in a
> construction of a smart pointer is explicit. Moving a unique_ptr is
> explicit. When you’re «casting» your on-a-stack-QFile to a some smart
> pointer, you’re telling the compiler (and other people who read the code)
> «trust me, I know what I’m doing, this is intended».

That I can agree with, but this goes back to the suggestion of our own smart 
QObject pointer classes. In non-compatibility mode, a function that adopts the 
passed object should only accept from another smart pointer. If you pass a 
naked pointer, it should reject and force you to clearly state that you know 
what you're doing.

-- 
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] unique_ptr and Qt, Take 2

2019-05-03 Thread Иван Комиссаров
Ahhh, it so hard to explain things.

Of course I am not suggesting to forbid creation of a QObject on a stack - it 
doesn’t make any sense to do that.

What I am talking about is that explicit is better than implicit. Taking an 
address of an object on a stack and passing it to a function that (possibly 
can) delete your object is not explicit. Wrapping that operation in a 
construction of a smart pointer is explicit. Moving a unique_ptr is explicit. 
When you’re «casting» your on-a-stack-QFile to a some smart pointer, you’re 
telling the compiler (and other people who read the code) «trust me, I know 
what I’m doing, this is intended».


> 4 мая 2019 г., в 0:43, Thiago Macieira  написал(а):
> 
> On Friday, 3 May 2019 13:00:52 PDT Иван Комиссаров wrote:
>> Which should be considered bad practice and banned on an API level
> 
> No way.
> 
> Are you going to forbid creation of QFile on the stack?
> 
> -- 
> 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] unique_ptr and Qt, Take 2

2019-05-03 Thread Thiago Macieira
On Friday, 3 May 2019 13:00:52 PDT Иван Комиссаров wrote:
> Which should be considered bad practice and banned on an API level

No way.

Are you going to forbid creation of QFile on the stack?

-- 
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] unique_ptr and Qt, Take 2

2019-05-03 Thread Giuseppe D'Angelo via Development

Il 04/05/19 00:33, Иван Комиссаров ha scritto:

Back to the topic - in case we really want to support the "stack case", I’d say 
shared_ptr is the only option (in combination with enable_shared_from_this which is 
already a kinda part of QObject, as mentioned above)


QObject ownership isn't shared, it's unique. A widget is in ONE 
hierarchy, which fixes its owning native window, its coordinate system, 
its Z order amongst its siblings; not N hierarchies.


--
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] unique_ptr and Qt, Take 2

2019-05-03 Thread Иван Комиссаров
It seems I am having problems expressing my thoughts, people don’t understand 
what I am trying to say=(

What I've meant is to have one allocation instead of two, yes, exactly.

Back to the topic - in case we really want to support the "stack case", I’d say 
shared_ptr is the only option (in combination with enable_shared_from_this 
which is already a kinda part of QObject, as mentioned above)

> 3 мая 2019 г., в 23:54, Giuseppe D'Angelo via Development 
>  написал(а):
> 
> Il 03/05/19 23:03, Иван Комиссаров ha scritto:
>> I’d say it’s an implementation detail - it *is* possible to implement the 
>> creation of QObjects more efficient than it is done now without «forcing» 
>> user to use objects on stack to avoid allocations.
> 
> Unless you also sacrifice binary compatibility, it's not possible.
> 
> What it is possible is to have one allocation instead of 2 (the object and 
> its dpointer), that's already been worked upon with a custom operator new, 
> check the patches on gerrit.
> 
> Anyhow this is entirely orthogonal to the original problem at hand: 
> ownership. We need to support the case of objects created on the stack (not 
> owned and owned).
> 
> Cheers,
> -- 
> 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
> 
> ___
> 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] unique_ptr and Qt, Take 2

2019-05-03 Thread Giuseppe D'Angelo via Development

Il 03/05/19 23:03, Иван Комиссаров ha scritto:


I’d say it’s an implementation detail - it *is* possible to implement 
the creation of QObjects more efficient than it is done now without 
«forcing» user to use objects on stack to avoid allocations.


Unless you also sacrifice binary compatibility, it's not possible.

What it is possible is to have one allocation instead of 2 (the object 
and its dpointer), that's already been worked upon with a custom 
operator new, check the patches on gerrit.


Anyhow this is entirely orthogonal to the original problem at hand: 
ownership. We need to support the case of objects created on the stack 
(not owned and owned).


Cheers,
--
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] unique_ptr and Qt, Take 2

2019-05-03 Thread Konstantin Shegunov
On Fri, May 3, 2019 at 11:02 PM Иван Комиссаров  wrote:

> Which should be considered bad practice and banned on an API level
>

On Fri, May 3, 2019 at 11:30 PM Иван Комиссаров  wrote:

> By forcing usage of smart pointers, of course.
>

That's a joke, right? Smart pointers aren't pointers, they are *stack*-based
(auto-storage) objects that manage pointers. I draw the line to pay one
heap allocation for binary compatibility not two, one of them being the
size of void * mind you, wherever I can help it.
C++ is a stack-based language, are you intending to reinvent it?
___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] unique_ptr and Qt, Take 2

2019-05-03 Thread Иван Комиссаров
Or maybe you can’t I didn’t think about the fact that public ctor allocates 
d_ptr itself… Need to think a bit more=(

> 3 мая 2019 г., в 23:03, Иван Комиссаров  написал(а):
> 
> You can use the same technique in qMakeChild as in std::make_shared - to 
> allocate MyObjectPrivate and space for the d_ptr in one go. Probably will 
> require some additional macroses, though, to hide the implementation 
> (sizeof(MyObjectPrivate)) in the cpp file.
> 
> I’d say it’s an implementation detail - it *is* possible to implement the 
> creation of QObjects more efficient than it is done now without «forcing» 
> user to use objects on stack to avoid allocations.
> 

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


Re: [Development] unique_ptr and Qt, Take 2

2019-05-03 Thread Иван Комиссаров
You can use the same technique in qMakeChild as in std::make_shared - to 
allocate MyObjectPrivate and space for the d_ptr in one go. Probably will 
require some additional macroses, though, to hide the implementation 
(sizeof(MyObjectPrivate)) in the cpp file.

I’d say it’s an implementation detail - it *is* possible to implement the 
creation of QObjects more efficient than it is done now without «forcing» user 
to use objects on stack to avoid allocations.

> 3 мая 2019 г., в 22:39, Konstantin Tokarev  написал(а):
> 
> 
> 
> 03.05.2019, 23:31, "Иван Комиссаров"  >:
>> By forcing usage of smart pointers, of course.
>> The moment you start writing
>> 
>> QWidget w1;
>> QWidget w2;
>> w1.setParent(QObjectSmartPointer());
>> 
>> It’s time to stop and think if you’re doing the right thing=) It is possible 
>> to pass an object on a stack to a unique_ptr/shared_ptr ctor, but that’s the 
>> problem of the person who's doing this, not the design flaw of smart 
>> pointers, right?
>> 
>> We need to make it intuitive to use smart pointer and hard to use them 
>> incorrectly. It is quite orthogonal to «support every corner case» which are 
>> QObjects on stack IMHO - there are always problems with them (except for the 
>> top-level objects).
>> 
>> Note, that we still need an old API for backward-compatility which works 
>> with QObjects on stack fine, so the user code won’t be broken in any case, 
>> but we might want to decide what use cases we do want to support and how 
>> users should write modern qt apps and what use cases are considered voodoo 
>> and bad practice.
> 
> IMO it would be resonable to drop specific behavior of QObject constructor 
> then to force unnecessary memory allocations upon users
> 
>> 
>>> 3 мая 2019 г., в 22:15, Giuseppe D'Angelo via Development 
>>>  написал(а):
>>> 
>>> Il 03/05/19 22:00, Иван Комиссаров ha scritto:
 Which should be considered bad practice and banned on an API level
 QWidget w2
 QWidget w1;
 w1.setParent();
 QWidget w1;
 QWidget w2
 w1.setParent();
>>> 
>>> Banned at an API level -- how, exactly?
>>> 
>>> Cheers,
>>> --
>>> 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
>>> 
>>> ___
>>> 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 
>> 
> 
> 
> -- 
> Regards,
> Konstantin

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


Re: [Development] unique_ptr and Qt, Take 2

2019-05-03 Thread Konstantin Tokarev


03.05.2019, 23:31, "Иван Комиссаров" :
> By forcing usage of smart pointers, of course.
> The moment you start writing
>
> QWidget w1;
> QWidget w2;
> w1.setParent(QObjectSmartPointer());
>
> It’s time to stop and think if you’re doing the right thing=) It is possible 
> to pass an object on a stack to a unique_ptr/shared_ptr ctor, but that’s the 
> problem of the person who's doing this, not the design flaw of smart 
> pointers, right?
>
> We need to make it intuitive to use smart pointer and hard to use them 
> incorrectly. It is quite orthogonal to «support every corner case» which are 
> QObjects on stack IMHO - there are always problems with them (except for the 
> top-level objects).
>
> Note, that we still need an old API for backward-compatility which works with 
> QObjects on stack fine, so the user code won’t be broken in any case, but we 
> might want to decide what use cases we do want to support and how users 
> should write modern qt apps and what use cases are considered voodoo and bad 
> practice.

IMO it would be resonable to drop specific behavior of QObject constructor then 
to force unnecessary memory allocations upon users

>
>> 3 мая 2019 г., в 22:15, Giuseppe D'Angelo via Development 
>>  написал(а):
>>
>> Il 03/05/19 22:00, Иван Комиссаров ha scritto:
>>> Which should be considered bad practice and banned on an API level
>>> QWidget w2
>>> QWidget w1;
>>> w1.setParent();
>>> QWidget w1;
>>> QWidget w2
>>> w1.setParent();
>>
>> Banned at an API level -- how, exactly?
>>
>> Cheers,
>> --
>> 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
>>
>> ___
>> 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


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


Re: [Development] unique_ptr and Qt, Take 2

2019-05-03 Thread Иван Комиссаров
By forcing usage of smart pointers, of course.
The moment you start writing

QWidget w1;
QWidget w2;
w1.setParent(QObjectSmartPointer());

It’s time to stop and think if you’re doing the right thing=) It is possible to 
pass an object on a stack to a unique_ptr/shared_ptr ctor, but that’s the 
problem of the person who's doing this, not the design flaw of smart pointers, 
right?

We need to make it intuitive to use smart pointer and hard to use them 
incorrectly. It is quite orthogonal to «support every corner case» which are 
QObjects on stack IMHO - there are always problems with them (except for the 
top-level objects).

Note, that we still need an old API for backward-compatility which works with 
QObjects on stack fine, so the user code won’t be broken in any case, but we 
might want to decide what use cases we do want to support and how users should 
write modern qt apps and what use cases are considered voodoo and bad practice.

> 3 мая 2019 г., в 22:15, Giuseppe D'Angelo via Development 
>  написал(а):
> 
> Il 03/05/19 22:00, Иван Комиссаров ha scritto:
>> Which should be considered bad practice and banned on an API level
>> QWidget w2
>> QWidget w1;
>> w1.setParent();
>> QWidget w1;
>> QWidget w2
>> w1.setParent();
> 
> Banned at an API level -- how, exactly?
> 
> Cheers,
> -- 
> 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
> 
> ___
> 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] unique_ptr and Qt, Take 2

2019-05-03 Thread Giuseppe D'Angelo via Development

Il 03/05/19 22:00, Иван Комиссаров ha scritto:

Which should be considered bad practice and banned on an API level

QWidget w2
QWidget w1;
w1.setParent();

QWidget w1;
QWidget w2
w1.setParent();


Banned at an API level -- how, exactly?

Cheers,
--
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] unique_ptr and Qt, Take 2

2019-05-03 Thread Иван Комиссаров
Which should be considered bad practice and banned on an API level

QWidget w2
QWidget w1;
w1.setParent();

QWidget w1;
QWidget w2
w1.setParent();

Which one will crash?=)

> 3 мая 2019 г., в 21:40, Thiago Macieira  
> написал(а):
> 
> On Friday, 3 May 2019 12:32:01 PDT Allan Sandfeld Jensen wrote:
>> Alternatively QObjects should be referenced counted, one reference could be
>> from a parent, but you could also strong reference with an explicit shared
>> pointer.
> 
> The problem with that is that you can create QObjects on the stack and those 
> mustn't be refcounted.
> 
> That said, the QPointer mechanism since 5.0 is basically refcounting, 
> Technically, it's a refcounted refcounter. Since it shares the same class as 
> QSharedPointer, it *has* the strong refcount inside, which could be used for 
> this.
> 
> -- 
> 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] unique_ptr and Qt, Take 2

2019-05-03 Thread Thiago Macieira
On Friday, 3 May 2019 12:32:01 PDT Allan Sandfeld Jensen wrote:
> Alternatively QObjects should be referenced counted, one reference could be
> from a parent, but you could also strong reference with an explicit shared
> pointer.

The problem with that is that you can create QObjects on the stack and those 
mustn't be refcounted.

That said, the QPointer mechanism since 5.0 is basically refcounting, 
Technically, it's a refcounted refcounter. Since it shares the same class as 
QSharedPointer, it *has* the strong refcount inside, which could be used for 
this.

-- 
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] unique_ptr and Qt, Take 2

2019-05-03 Thread Allan Sandfeld Jensen
On Freitag, 3. Mai 2019 20:24:07 CEST Thiago Macieira wrote:
> On Friday, 3 May 2019 10:22:20 PDT Daniel Teske wrote:
> > std::unique_ptr rightButton =
> > std::make_unique("RIGHT");
> > layout->addWidget(std::move(rightButton));
> 
> The problem in this particular example is that once you've added the widget,
> the rightButton smart pointer no longer has a pointer. You can't continue
> to set up your push button. In most cases, this is just a matter of moving
> the set up before the addition / reparenting, or using the other idiom
> where the object is never in a smart pointer in the first place.
> 
> So this begs the question of whether std::unique_ptr is the best smart
> pointer for this scenario. Would it make sense to create one that
> understands parent- child relationship?

I would prefer that too. Something like a QPointer except it takes strong 
instead of weak reference when holding objects without a parent. This means 
you could pass it to an object taking ownership, and it would transition from 
strong to weak, but still be valid.

Alternatively QObjects should be referenced counted, one reference could be 
from a parent, but you could also strong reference with an explicit shared 
pointer.

'Allan



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


Re: [Development] unique_ptr and Qt, Take 2

2019-05-03 Thread Иван Комиссаров
That’s exactly why observer_ptr should not* be implemented as alias to a raw 
pointer; the main difference is that constructor from T* is explicit and 
there’s no implicit cast from observer_ptr to unique_ptr, so your example will 
not compile =)

* well, the clang implementation I used forbids implicit cast, not sure how it 
will (if it ever will) be implemented in c++20

> 3 мая 2019 г., в 21:09, Konstantin Ritt  написал(а):
> 
> Ivan,
> 
> note that observer_ptr is mostly like
> 
> template
> using observer_ptr = T*;
> 
> so what about
> 
> 
> layout2->addWidget(layout->addWidget(make_unique("right")))->setFlat(true);
> ?
> 
> 
> Regards,
> Konstantin
> 

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


Re: [Development] unique_ptr and Qt, Take 2

2019-05-03 Thread Konstantin Ritt
Just wandering, what `QObject:: children ()` shall return? ;p


Konstantin

пт, 3 мая 2019 г., 22:09 Konstantin Ritt :

> Ivan,
>
> note that observer_ptr is mostly like
>
> templateusing observer_ptr = T*;
>
>
> so what about
>
>
> layout2->addWidget(layout->addWidget(make_unique("right")))->setFlat(true);
>
> ?
>
>
> Regards,
> Konstantin
>
>
> пт, 3 мая 2019 г., 21:41 Иван Комиссаров :
>
>> Thiago, can you please elaborate how you see this?
>>
>> For a simple TreeItem a pair of std::unique_ptr/std::observer_ptr should
>> be enough (with a bunch of convenience methods to insert children):
>>
>> struct TreeItem
>> {
>>observer_ptr parent;
>>vector> children;
>> };
>>
>> Yes, the code becomes a bit verbose, but the ownership transfer is now
>> visible with those (ugly) std::moves.
>>
>> I can think of an alternative of using shared pointers (since we already
>> have a QPointer aka WeakPointer) but I think it gives too much
>> overhead just to support corner cases.
>>
>> If QLayout::addWidget() will return an observer_ptr*, you can just do
>>
>> auto button = layout->addWidget(make_unique(«RIGHT»));
>> button->setFlat(true);
>>
>> * ok, you need a template version of addWidget for that, but since c++ is
>> all about templates these days it doesn’t really a disadvantage
>>
>>
>> > 3 мая 2019 г., в 20:24, Thiago Macieira 
>> написал(а):
>> >
>> > On Friday, 3 May 2019 10:22:20 PDT Daniel Teske wrote:
>> >> std::unique_ptr rightButton =
>> >> std::make_unique("RIGHT");
>> >> layout->addWidget(std::move(rightButton));
>> >
>> > The problem in this particular example is that once you've added the
>> widget,
>> > the rightButton smart pointer no longer has a pointer. You can't
>> continue to
>> > set up your push button. In most cases, this is just a matter of moving
>> the
>> > set up before the addition / reparenting, or using the other idiom
>> where the
>> > object is never in a smart pointer in the first place.
>> >
>> > So this begs the question of whether std::unique_ptr is the best smart
>> pointer
>> > for this scenario. Would it make sense to create one that understands
>> parent-
>> > child relationship?
>> >
>> > --
>> > 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
>>
>
___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] unique_ptr and Qt, Take 2

2019-05-03 Thread Thiago Macieira
On Friday, 3 May 2019 12:04:40 PDT Giuseppe D'Angelo via Development wrote:
> Anyhow, I too feel that we may need a dedicated smart pointer class for
> this, to catch all the corner cases and allow the existing flow of
> 
> 1) create something
> 2) (re)parent it
> 3) keep using that something via a non-owning pointer.

Same here. I think Daniel is on to something and we really should explore 
having smart pointers in Qt 6, but at this point I'm not convinced 
std::unique_ptr alone is it. I'd like to see what we could achieve with a 
QObject-specific smart pointer that understood ownership-taking functions 
(setParent, addWidget, etc.) and observing-only API (like connect()).

-- 
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] unique_ptr and Qt, Take 2

2019-05-03 Thread Thiago Macieira
On Friday, 3 May 2019 11:41:16 PDT Иван Комиссаров wrote:
> auto button = layout->addWidget(make_unique(«RIGHT»));
> button->setFlat(true);

The problem with code that has pre- and post-addition setup is that now you 
have two objects in the stack, which complicates your stack frame. The 
compilers aren't currently smart enough to deduce std::unique_ptr whose 
payload is completely null and can be early-destroyed.

I'm wary of making user code less readable, but it's something we should do if 
it's for a good reason.

-- 
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] unique_ptr and Qt, Take 2

2019-05-03 Thread Konstantin Ritt
Ivan,

note that observer_ptr is mostly like

templateusing observer_ptr = T*;


so what about


layout2->addWidget(layout->addWidget(make_unique("right")))->setFlat(true);

?


Regards,
Konstantin


пт, 3 мая 2019 г., 21:41 Иван Комиссаров :

> Thiago, can you please elaborate how you see this?
>
> For a simple TreeItem a pair of std::unique_ptr/std::observer_ptr should
> be enough (with a bunch of convenience methods to insert children):
>
> struct TreeItem
> {
>observer_ptr parent;
>vector> children;
> };
>
> Yes, the code becomes a bit verbose, but the ownership transfer is now
> visible with those (ugly) std::moves.
>
> I can think of an alternative of using shared pointers (since we already
> have a QPointer aka WeakPointer) but I think it gives too much
> overhead just to support corner cases.
>
> If QLayout::addWidget() will return an observer_ptr*, you can just do
>
> auto button = layout->addWidget(make_unique(«RIGHT»));
> button->setFlat(true);
>
> * ok, you need a template version of addWidget for that, but since c++ is
> all about templates these days it doesn’t really a disadvantage
>
>
> > 3 мая 2019 г., в 20:24, Thiago Macieira 
> написал(а):
> >
> > On Friday, 3 May 2019 10:22:20 PDT Daniel Teske wrote:
> >> std::unique_ptr rightButton =
> >> std::make_unique("RIGHT");
> >> layout->addWidget(std::move(rightButton));
> >
> > The problem in this particular example is that once you've added the
> widget,
> > the rightButton smart pointer no longer has a pointer. You can't
> continue to
> > set up your push button. In most cases, this is just a matter of moving
> the
> > set up before the addition / reparenting, or using the other idiom where
> the
> > object is never in a smart pointer in the first place.
> >
> > So this begs the question of whether std::unique_ptr is the best smart
> pointer
> > for this scenario. Would it make sense to create one that understands
> parent-
> > child relationship?
> >
> > --
> > 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
>
___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] unique_ptr and Qt, Take 2

2019-05-03 Thread Giuseppe D'Angelo via Development

Hi,

Il 03/05/19 19:22, Daniel Teske ha scritto:

The first half of the program would thus look like:

QWidget widget;
QHBoxLayout *layout = widget.makeChild();

QPushButton *leftButton = widget.makeChild("LEFT");
layout->addWidget(leftButton);

std::unique_ptr rightButton = 
std::make_unique("RIGHT");

layout->addWidget(std::move(rightButton));


To really, really, really nitpick, this last line is (or feels) wrong: 
layouts do not take ownership of the widgets they manage. An ownership 
transfer MAY happen immediately (if the layout is installed) or later 
(as soon as the layout is installed).




For second half, the naive transformation:

{
     QMenu menu;
     auto act = std::make_unique("Action!");
     menu.addAction(act.get());
menu.exec(leftButton->mapToGlobal(leftButton->rect().bottomLeft()));
}

does no longer leak memory, instead the action is freed at the end of 
the scope as its still owned by the unique_ptr.


Well, the super-naive transformation is actually already available:


menu.addAction("Action!");


which correctly returns an action parented to the menu.


Anyhow, I too feel that we may need a dedicated smart pointer class for 
this, to catch all the corner cases and allow the existing flow of


1) create something
2) (re)parent it
3) keep using that something via a non-owning pointer.

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] unique_ptr and Qt, Take 2

2019-05-03 Thread Иван Комиссаров
Thiago, can you please elaborate how you see this?

For a simple TreeItem a pair of std::unique_ptr/std::observer_ptr should be 
enough (with a bunch of convenience methods to insert children):

struct TreeItem
{
   observer_ptr parent;
   vector> children;
};

Yes, the code becomes a bit verbose, but the ownership transfer is now visible 
with those (ugly) std::moves.

I can think of an alternative of using shared pointers (since we already have a 
QPointer aka WeakPointer) but I think it gives too much overhead just 
to support corner cases.

If QLayout::addWidget() will return an observer_ptr*, you can just do

auto button = layout->addWidget(make_unique(«RIGHT»));
button->setFlat(true);

* ok, you need a template version of addWidget for that, but since c++ is all 
about templates these days it doesn’t really a disadvantage


> 3 мая 2019 г., в 20:24, Thiago Macieira  
> написал(а):
> 
> On Friday, 3 May 2019 10:22:20 PDT Daniel Teske wrote:
>> std::unique_ptr rightButton =
>> std::make_unique("RIGHT");
>> layout->addWidget(std::move(rightButton));
> 
> The problem in this particular example is that once you've added the widget, 
> the rightButton smart pointer no longer has a pointer. You can't continue to 
> set up your push button. In most cases, this is just a matter of moving the 
> set up before the addition / reparenting, or using the other idiom where the 
> object is never in a smart pointer in the first place.
> 
> So this begs the question of whether std::unique_ptr is the best smart 
> pointer 
> for this scenario. Would it make sense to create one that understands parent-
> child relationship?
> 
> -- 
> 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] unique_ptr and Qt, Take 2

2019-05-03 Thread Scott Bloom
On Friday, 3 May 2019 10:22:20 PDT Daniel Teske wrote:
> std::unique_ptr rightButton = 
> std::make_unique("RIGHT");
> layout->addWidget(std::move(rightButton));

The problem in this particular example is that once you've added the widget, 
the rightButton smart pointer no longer has a pointer. You can't continue to 
set up your push button. In most cases, this is just a matter of moving the set 
up before the addition / reparenting, or using the other idiom where the object 
is never in a smart pointer in the first place.

So this begs the question of whether std::unique_ptr is the best smart pointer 
for this scenario. Would it make sense to create one that understands parent- 
child relationship?

--
I just survived a painful problem dealing with this exact issue.

Long story short, a child widget, had to survive the parent, it was created 
correctly with parent being null, but in adding it to a layout, changed that of 
course.

The solution was to set the parent back to null, when the "non-layout" parent's 
destructor was called.

A Qt Smart Pointer, that allowed "unique" but another that also allowed for 
"Shared" depending on the case, that took into account the Qt parent child 
relationship, would be a great addition

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


Re: [Development] unique_ptr and Qt, Take 2

2019-05-03 Thread Niels Ole Salscheider via Development

On 03.05.19 11:24, Thiago Macieira wrote:

On Friday, 3 May 2019 10:22:20 PDT Daniel Teske wrote:

std::unique_ptr rightButton =
std::make_unique("RIGHT");
layout->addWidget(std::move(rightButton));


The problem in this particular example is that once you've added the widget,
the rightButton smart pointer no longer has a pointer. You can't continue to
set up your push button. In most cases, this is just a matter of moving the
set up before the addition / reparenting, or using the other idiom where the
object is never in a smart pointer in the first place.

So this begs the question of whether std::unique_ptr is the best smart pointer
for this scenario. Would it make sense to create one that understands parent-
child relationship?
I agree that the ownership transfer of the unique_ptr feels a bit 
cumbersome and I also don't like that makeChild still returns raw 
pointers. Maybe something that understands the parent-child relationship 
can work better but I wonder how exactly it would look like.


Maybe using a combination of weak_ptr and shared_ptr would make the API 
easier to use?

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


Re: [Development] unique_ptr and Qt, Take 2

2019-05-03 Thread Lutor, Zoltán
+1 from my side.

Explicit ownership declaration is the king. always - all other solutions are 
paid with sweat and blood. but mainly with blood... ;)

Zoltan

On Friday, May 3, 2019, Daniel Teske wrote:
> Hi,
> 
> a year back I wrote a patch that added unique_ptr apis to most of 
> qtbase. I still think that would be a good addition to Qt, and thus I've 
> updated the patch with the feedback gained at the Contributor Summit 
> last year and taking into account that with Qt6, binary compatibility is 
> not required. The result is: https://codereview.qt-project.org/#/c/260618/
> 
> Since not everyone remembers last years mail, I'll explain the problem 
> that patch is trying to solve, but won't go into all the details:
> Consider this small program:
> 
> QWidget widget;
> QHBoxLayout *layout = new QHBoxLayout();
> QPushButton *leftButton = new QPushButton("LEFT", ); // Owned by 
> widget
> layout->addWidget(leftButton); // No Ownership transfer
> 
> QPushButton* rightButton = new QPushButton("RIGHT"); // No owner
> layout->addWidget(rightButton);   // Ownership transfer
> 
> QObject::connect(leftButton, ::clicked,
>  [leftButton]{
>  QMenu menu;
>  auto act = new QAction("Action!"); // No Owner
>  menu.addAction(act); // No Ownership transfer
> menu.exec(leftButton->mapToGlobal(leftButton->rect().bottomLeft()));
> });
> widget.show();
> 
> In that program:
> 
> * The left button is owned at construction by the parent.
> * The right button is created unowned, but adding a widget to a layout 
> automatically sets the parent
> * The action is created unowned, and is leaked because addAction does 
> not set the parent.
> 
> That is, even though:
> 
> * layout->addWidget(new QPushButton()) and
> * menu->addAction(new QAction())
> 
> look very similar, the later leaks memory.
> 
> That's a less than ideal api. With Qt6 there's a opportunity to leverage 
> unique_ptr to ensure that memory is not leaked.
> 
> The patch adds two ways to create new QObjects:
> 
> * std::make_unique("LEFT"); and
> * parent->makeChild("RIGHT");
> * adds various overloads for ownership transfer
> 
> The first half of the program would thus look like:
> 
> QWidget widget;
> QHBoxLayout *layout = widget.makeChild();
> 
> QPushButton *leftButton = widget.makeChild("LEFT");
> layout->addWidget(leftButton);
> 
> std::unique_ptr rightButton = 
> std::make_unique("RIGHT");
> layout->addWidget(std::move(rightButton));
> 
> For second half, the naive transformation:
> 
> {
>  QMenu menu;
>  auto act = std::make_unique("Action!");
>  menu.addAction(act.get());
> menu.exec(leftButton->mapToGlobal(leftButton->rect().bottomLeft()));
> }
> 
> does no longer leak memory, instead the action is freed at the end of 
> the scope as its still owned by the unique_ptr.
> 
> I believe that Qt6 is a unique opportunity to add apis for better memory 
> management to Qt.
> 
> So, who thinks that this is something that ought to be a Qt6 feature?
> 
> And who wants to actually help make that happen?
> 
> daniel
> 
>
___
Development mailing list
Development@qt-project.org
https://lists.qt-project.org/listinfo/development


Re: [Development] unique_ptr and Qt, Take 2

2019-05-03 Thread Thiago Macieira
On Friday, 3 May 2019 10:22:20 PDT Daniel Teske wrote:
> std::unique_ptr rightButton =
> std::make_unique("RIGHT");
> layout->addWidget(std::move(rightButton));

The problem in this particular example is that once you've added the widget, 
the rightButton smart pointer no longer has a pointer. You can't continue to 
set up your push button. In most cases, this is just a matter of moving the 
set up before the addition / reparenting, or using the other idiom where the 
object is never in a smart pointer in the first place.

So this begs the question of whether std::unique_ptr is the best smart pointer 
for this scenario. Would it make sense to create one that understands parent-
child relationship?

-- 
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] unique_ptr and Qt, Take 2

2019-05-03 Thread Иван Комиссаров
IMHO, it should be a Qt6 feature. It’s awesome.

However, I liked the idea (is it deprecated or what?) of a template method
template 
std::observer_ptr 
qMakeChild(gsll::not_null> parent, Args… args)
{
return parent->adoptChild(std::make_unique(args));
}

With that method, you don’t need to implement stuff like 
QLibrary::QLibrary(QParentPtr parent, const QString ),
You just need to split ctor into safe and unsafe versions and deprecate unsafe.

Maybe I’m asking too much, but it would be nice get rid of raw pointers 
completely switching to pair std::unique_ptr/std::observer_ptr

> 3 мая 2019 г., в 19:22, Daniel Teske  написал(а):
> 
> So, who thinks that this is something that ought to be a Qt6 feature? 
> 
> And who wants to actually help make that happen? 
> 
> daniel 
> 
> ___
> 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