public inbox for gcc-bugs@sourceware.org
help / color / mirror / Atom feed
* [Bug libstdc++/42242]  New: vector::resize unnecessarily calls null constructor
@ 2009-12-01 18:14 igodard at pacbell dot net
  2009-12-01 18:22 ` [Bug libstdc++/42242] " redi at gcc dot gnu dot org
                   ` (12 more replies)
  0 siblings, 13 replies; 14+ messages in thread
From: igodard at pacbell dot net @ 2009-12-01 18:14 UTC (permalink / raw)
  To: gcc-bugs

This code shows that the resize member function is calling the null constructor
even when the size does not need to be changed.

#include    <vector>
#include    <iostream>
class c {
public:
            c() { std::cerr << "c null constructor called\n"; }
            c(int i) : i(i) {}
    int     i;
    };

int main() {
    std::vector<c>f;
    f.push_back(c(0));
    f.resize(1);
    return 0;
    }


-- 
           Summary: vector::resize unnecessarily calls null constructor
           Product: gcc
           Version: 4.4.1
            Status: UNCONFIRMED
          Severity: normal
          Priority: P3
         Component: libstdc++
        AssignedTo: unassigned at gcc dot gnu dot org
        ReportedBy: igodard at pacbell dot net


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42242


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libstdc++/42242] vector::resize unnecessarily calls null constructor
  2009-12-01 18:14 [Bug libstdc++/42242] New: vector::resize unnecessarily calls null constructor igodard at pacbell dot net
@ 2009-12-01 18:22 ` redi at gcc dot gnu dot org
  2009-12-01 18:31 ` redi at gcc dot gnu dot org
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: redi at gcc dot gnu dot org @ 2009-12-01 18:22 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #1 from redi at gcc dot gnu dot org  2009-12-01 18:21 -------
this is caused by the default argument to resize:

void
resize(size_type __new_size, value_type __x = value_type());


It would be possible to avoid the default construction by replacing that member
with two overloads of resize, but I'm not sure it's worth doing.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42242


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libstdc++/42242] vector::resize unnecessarily calls null constructor
  2009-12-01 18:14 [Bug libstdc++/42242] New: vector::resize unnecessarily calls null constructor igodard at pacbell dot net
  2009-12-01 18:22 ` [Bug libstdc++/42242] " redi at gcc dot gnu dot org
@ 2009-12-01 18:31 ` redi at gcc dot gnu dot org
  2009-12-01 18:33 ` pinskia at gcc dot gnu dot org
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: redi at gcc dot gnu dot org @ 2009-12-01 18:31 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #2 from redi at gcc dot gnu dot org  2009-12-01 18:30 -------
On second thoughts, it might be necessary to split it into two overloads for
C++1x, because this should work:

#include <vector>

struct moveable {
    explicit moveable(int) { }
    moveable(const moveable&) = delete;
    moveable(moveable&&) { }
};

int main()
{
    std::vector<moveable> v;
    moveable m(0);
    v.resize(1, m);
}


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42242


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libstdc++/42242] vector::resize unnecessarily calls null constructor
  2009-12-01 18:14 [Bug libstdc++/42242] New: vector::resize unnecessarily calls null constructor igodard at pacbell dot net
  2009-12-01 18:22 ` [Bug libstdc++/42242] " redi at gcc dot gnu dot org
  2009-12-01 18:31 ` redi at gcc dot gnu dot org
@ 2009-12-01 18:33 ` pinskia at gcc dot gnu dot org
  2009-12-01 18:34 ` pinskia at gcc dot gnu dot org
                   ` (9 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2009-12-01 18:33 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #3 from pinskia at gcc dot gnu dot org  2009-12-01 18:33 -------
(In reply to comment #1) 
> It would be possible to avoid the default construction by replacing that member
> with two overloads of resize, but I'm not sure it's worth doing.

The C++03 standard only lists the function with the default value so this is
invalid.


-- 

pinskia at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |INVALID


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42242


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libstdc++/42242] vector::resize unnecessarily calls null constructor
  2009-12-01 18:14 [Bug libstdc++/42242] New: vector::resize unnecessarily calls null constructor igodard at pacbell dot net
                   ` (2 preceding siblings ...)
  2009-12-01 18:33 ` pinskia at gcc dot gnu dot org
@ 2009-12-01 18:34 ` pinskia at gcc dot gnu dot org
  2009-12-01 18:37 ` redi at gcc dot gnu dot org
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2009-12-01 18:34 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #4 from pinskia at gcc dot gnu dot org  2009-12-01 18:34 -------
(In reply to comment #2)
> On second thoughts, it might be necessary to split it into two overloads for
> C++1x, because this should work:

But std::vector::resize (size_type sz, T c = T()); is the only one listed at
least in C++03.  What does C++1x say about that function?  You might need to
raise this to the C++ standards committee.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42242


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libstdc++/42242] vector::resize unnecessarily calls null constructor
  2009-12-01 18:14 [Bug libstdc++/42242] New: vector::resize unnecessarily calls null constructor igodard at pacbell dot net
                   ` (3 preceding siblings ...)
  2009-12-01 18:34 ` pinskia at gcc dot gnu dot org
@ 2009-12-01 18:37 ` redi at gcc dot gnu dot org
  2009-12-01 18:41 ` [Bug libstdc++/42242] vector::resize could be split up into two different functions pinskia at gcc dot gnu dot org
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: redi at gcc dot gnu dot org @ 2009-12-01 18:37 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #5 from redi at gcc dot gnu dot org  2009-12-01 18:37 -------
(In reply to comment #2)
> On second thoughts, it might be necessary to split it into two overloads for
> C++1x, because this should work:

Gah, ignore that, I'm talking rubbish and that shouldn't work

Andrew, the standard would allow two overloads instead of one, see
[member.functions]/2 - and the C++1x draft specifies two separate overloads. 
It's a reasonable enhancement request IMHO, but necessarily not a bug.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42242


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libstdc++/42242] vector::resize could be split up into two different functions
  2009-12-01 18:14 [Bug libstdc++/42242] New: vector::resize unnecessarily calls null constructor igodard at pacbell dot net
                   ` (4 preceding siblings ...)
  2009-12-01 18:37 ` redi at gcc dot gnu dot org
@ 2009-12-01 18:41 ` pinskia at gcc dot gnu dot org
  2009-12-01 18:54 ` redi at gcc dot gnu dot org
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: pinskia at gcc dot gnu dot org @ 2009-12-01 18:41 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #6 from pinskia at gcc dot gnu dot org  2009-12-01 18:40 -------
(In reply to comment #5)
> (In reply to comment #2)
> > On second thoughts, it might be necessary to split it into two overloads for
> > C++1x, because this should work:
> 
> Gah, ignore that, I'm talking rubbish and that shouldn't work
> 
> Andrew, the standard would allow two overloads instead of one, see
> [member.functions]/2

hmm, I missed that :).

Note doesn't a change like this change the ABI?  Which means it has to wait
until v7?


-- 

pinskia at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
           Severity|normal                      |enhancement
             Status|RESOLVED                    |UNCONFIRMED
           Keywords|                            |missed-optimization
         Resolution|INVALID                     |
            Summary|vector::resize unnecessarily|vector::resize could be
                   |calls null constructor      |split up into two different
                   |                            |functions


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42242


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libstdc++/42242] vector::resize could be split up into two different functions
  2009-12-01 18:14 [Bug libstdc++/42242] New: vector::resize unnecessarily calls null constructor igodard at pacbell dot net
                   ` (5 preceding siblings ...)
  2009-12-01 18:41 ` [Bug libstdc++/42242] vector::resize could be split up into two different functions pinskia at gcc dot gnu dot org
@ 2009-12-01 18:54 ` redi at gcc dot gnu dot org
  2009-12-01 19:01 ` chris at bubblescope dot net
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: redi at gcc dot gnu dot org @ 2009-12-01 18:54 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #7 from redi at gcc dot gnu dot org  2009-12-01 18:54 -------
Yes, it would be an ABI change, although that symbol isn't exported from the
library.

vector::resize() was changed from one function to two in the n2284 draft, as a
result of n1858, the rationale is the same as for deque, see
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1858.html#23.2.1.2%20-%20deque%20capacity


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42242


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libstdc++/42242] vector::resize could be split up into two different functions
  2009-12-01 18:14 [Bug libstdc++/42242] New: vector::resize unnecessarily calls null constructor igodard at pacbell dot net
                   ` (6 preceding siblings ...)
  2009-12-01 18:54 ` redi at gcc dot gnu dot org
@ 2009-12-01 19:01 ` chris at bubblescope dot net
  2009-12-01 19:02 ` igodard at pacbell dot net
                   ` (4 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: chris at bubblescope dot net @ 2009-12-01 19:01 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #8 from chris at bubblescope dot net  2009-12-01 19:01 -------
The only change in C++0x is that a new function is added, so it won't break any
existing code, and we will be able to add it without moving to v7.


-- 

chris at bubblescope dot net changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |chris at bubblescope dot net


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42242


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libstdc++/42242] vector::resize could be split up into two different functions
  2009-12-01 18:14 [Bug libstdc++/42242] New: vector::resize unnecessarily calls null constructor igodard at pacbell dot net
                   ` (7 preceding siblings ...)
  2009-12-01 19:01 ` chris at bubblescope dot net
@ 2009-12-01 19:02 ` igodard at pacbell dot net
  2009-12-01 19:07 ` chris at bubblescope dot net
                   ` (3 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: igodard at pacbell dot net @ 2009-12-01 19:02 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #9 from igodard at pacbell dot net  2009-12-01 19:02 -------
FWIW, I think it is a design error in the standard. The resize function seems
to be designed from an assumption that the vector type T is POD. The second
argument should not be a T, it should be a constructor, so any added cells (if
the resize extends the vector) are constructed in place rather than the
construct-a-temp/copy-construct/destruct sequence. Or there should be no second
argument and the null constructor used implicitly iff actually needed.

The actual usecase (that prompted the report) used the vector as a state holder
in a recursive tree walk; the resize was used to cut back the state when
returning from a leaf. The null constructor is seriously non-trivial for the
node type, involving considerable file activity that could fail (a file system
search). The workaround was simple when the problem was discovered: have a
do-nothing null constructor for the vector, with the "real" null constructor
turned into a constructor taking a dummy argument. Of course, that wound up
getting exposed into the exported interface, and required macros to hide. :-(


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42242


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libstdc++/42242] vector::resize could be split up into two different functions
  2009-12-01 18:14 [Bug libstdc++/42242] New: vector::resize unnecessarily calls null constructor igodard at pacbell dot net
                   ` (8 preceding siblings ...)
  2009-12-01 19:02 ` igodard at pacbell dot net
@ 2009-12-01 19:07 ` chris at bubblescope dot net
  2009-12-01 19:26 ` igodard at pacbell dot net
                   ` (2 subsequent siblings)
  12 siblings, 0 replies; 14+ messages in thread
From: chris at bubblescope dot net @ 2009-12-01 19:07 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #10 from chris at bubblescope dot net  2009-12-01 19:07 -------
Anyway, the result of this bug is that the fix to resize() given in the latest
draft of C++0x should be applied. The resulting code would only be invoked if
you ask the compiler to use C++0x mode, but if care about performance you
should be doing this anyway, I suspect your types may well benefit from rvalue
references.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42242


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libstdc++/42242] vector::resize could be split up into two different functions
  2009-12-01 18:14 [Bug libstdc++/42242] New: vector::resize unnecessarily calls null constructor igodard at pacbell dot net
                   ` (9 preceding siblings ...)
  2009-12-01 19:07 ` chris at bubblescope dot net
@ 2009-12-01 19:26 ` igodard at pacbell dot net
  2009-12-01 19:29 ` chris at bubblescope dot net
  2009-12-02  0:01 ` paolo dot carlini at oracle dot com
  12 siblings, 0 replies; 14+ messages in thread
From: igodard at pacbell dot net @ 2009-12-01 19:26 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #11 from igodard at pacbell dot net  2009-12-01 19:26 -------
Subject: Re:  vector::resize could be split up into two
 different functions

We await r-value references with baited breath :-)

chris at bubblescope dot net wrote:
> ------- Comment #10 from chris at bubblescope dot net  2009-12-01 19:07 -------
> Anyway, the result of this bug is that the fix to resize() given in the latest
> draft of C++0x should be applied. The resulting code would only be invoked if
> you ask the compiler to use C++0x mode, but if care about performance you
> should be doing this anyway, I suspect your types may well benefit from rvalue
> references.
>
>
>   


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42242


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libstdc++/42242] vector::resize could be split up into two different functions
  2009-12-01 18:14 [Bug libstdc++/42242] New: vector::resize unnecessarily calls null constructor igodard at pacbell dot net
                   ` (10 preceding siblings ...)
  2009-12-01 19:26 ` igodard at pacbell dot net
@ 2009-12-01 19:29 ` chris at bubblescope dot net
  2009-12-02  0:01 ` paolo dot carlini at oracle dot com
  12 siblings, 0 replies; 14+ messages in thread
From: chris at bubblescope dot net @ 2009-12-01 19:29 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #12 from chris at bubblescope dot net  2009-12-01 19:28 -------
No need to wait, they are in g++ 4.3 and 4.4, use -std=c++0x to activate
features from C++0x. Obviously they are all subject to change, but are now
fairly close to standardised.


-- 


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42242


^ permalink raw reply	[flat|nested] 14+ messages in thread

* [Bug libstdc++/42242] vector::resize could be split up into two different functions
  2009-12-01 18:14 [Bug libstdc++/42242] New: vector::resize unnecessarily calls null constructor igodard at pacbell dot net
                   ` (11 preceding siblings ...)
  2009-12-01 19:29 ` chris at bubblescope dot net
@ 2009-12-02  0:01 ` paolo dot carlini at oracle dot com
  12 siblings, 0 replies; 14+ messages in thread
From: paolo dot carlini at oracle dot com @ 2009-12-02  0:01 UTC (permalink / raw)
  To: gcc-bugs



------- Comment #13 from paolo dot carlini at oracle dot com  2009-12-02 00:01 -------
This is essentially PR32618, see the last audit trail entries, in particular.
As far as I know my last remark is still an issue (I told privately Howard but
then I dropped it): without Concepts, it's quite hard to implement the two
separate resize and at the same time keep on guaranteeing that the std::vector
class can be explicitly instantiated for non-default constructible types. If
somebody is aware of decently simple ways to do that for 4.5.0, I'm all ears...

*** This bug has been marked as a duplicate of 32618 ***


-- 

paolo dot carlini at oracle dot com changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
             Status|UNCONFIRMED                 |RESOLVED
         Resolution|                            |DUPLICATE


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=42242


^ permalink raw reply	[flat|nested] 14+ messages in thread

end of thread, other threads:[~2009-12-02  0:01 UTC | newest]

Thread overview: 14+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2009-12-01 18:14 [Bug libstdc++/42242] New: vector::resize unnecessarily calls null constructor igodard at pacbell dot net
2009-12-01 18:22 ` [Bug libstdc++/42242] " redi at gcc dot gnu dot org
2009-12-01 18:31 ` redi at gcc dot gnu dot org
2009-12-01 18:33 ` pinskia at gcc dot gnu dot org
2009-12-01 18:34 ` pinskia at gcc dot gnu dot org
2009-12-01 18:37 ` redi at gcc dot gnu dot org
2009-12-01 18:41 ` [Bug libstdc++/42242] vector::resize could be split up into two different functions pinskia at gcc dot gnu dot org
2009-12-01 18:54 ` redi at gcc dot gnu dot org
2009-12-01 19:01 ` chris at bubblescope dot net
2009-12-01 19:02 ` igodard at pacbell dot net
2009-12-01 19:07 ` chris at bubblescope dot net
2009-12-01 19:26 ` igodard at pacbell dot net
2009-12-01 19:29 ` chris at bubblescope dot net
2009-12-02  0:01 ` paolo dot carlini at oracle dot com

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).