[RESOLVED] Subtle differences in std::vector
Hello,
I am studying subtle differences in the implementation of std::vector<T> for Microsoft and GCC compilers.
The program shown below gives different output for the two compilers. You need to look in the comments to see the outputs. I perfectly understand the output from GCC.
Output from GCC does this:
- CTOR 1: Creates one dummy on the stack for the vector's ctor
- Uses this dummy to initialize the vector
- DTOR 1: Deletes this dummy off the stack when vector's ctor is done.
- DTOR 2-3: vector's clear function deletes two dummys.
However, I don't understand why the Microsoft compiler has different output. I perused ISO/IEC 14882:2003 but could not find these implementation details.
- Shouldn't this stuff be specified?
- Why do these compilers seem to have implementation freedom?
Code:
#include <vector>
#include <iostream>
struct dummy
{
static unsigned ctor_count;
static unsigned dtor_count;
dummy()
{
++ctor_count;
std::cout << "C-TOR of dummy" << std::endl;
}
~dummy(void)
{
++dtor_count;
std::cout << "D-TOR of dummy" << std::endl;
}
};
unsigned dummy::ctor_count;
unsigned dummy::dtor_count;
int main(void)
{
std::vector<dummy> vd(2u);
vd.clear();
std::cout << "JUST AFTER CLEAR!" << std::endl;
std::cout << "Number of dummy ctors: " << dummy::ctor_count << std::endl;
std::cout << "Number of dummy dtors: " << dummy::dtor_count << std::endl;
}
/*
Visual Studio 2010
------------------
C-TOR of dummy
D-TOR of dummy
C-TOR of dummy
D-TOR of dummy
D-TOR of dummy
D-TOR of dummy
JUST AFTER CLEAR!
Number of dummy ctors: 2
Number of dummy dtors: 4
*/
/*
GCC 4.5.2
$ g++ -Wall -Wextra -pedantic -std=c++0x -O3 test.cpp -o test.exe
------------------
C-TOR of dummy
D-TOR of dummy
D-TOR of dummy
D-TOR of dummy
JUST AFTER CLEAR!
Number of dummy ctors: 1
Number of dummy dtors: 3
*/
Re: Subtle differences in std::vector
Because, like the C++ standard itself, the standards committee doesn't want to dictate implementation details, just implementation behavior. This leaves the details up to the various developers, to come up with whatever optimizations they want.
Viggy
Re: Subtle differences in std::vector
Oh, and I assume that you enabled full optimization with the MS compile?
Viggy
Re: Subtle differences in std::vector
Quote:
Originally Posted by
MrViggy
...the standards committee doesn't want to dictate implementation details, just implementation behavior...
I can understand that. In fact, for a day or so, I was content to just figure it along those lines.
But is this really an implementation detail? What if someone wanted to use some ctor/dtor counting for memory management or something like that? The implementations would behave differently.
I keep asking because I am implementing a subset of the STL for tiny embedded systems, and I would like to be consistent with other known implementations.
Sincerely, Chris.
Re: Subtle differences in std::vector
Quote:
Originally Posted by
dude_1967
I can understand that. In fact, for a day or so, I was content to just figure it along those lines.
But is this really an implementation detail? What if someone wanted to use some ctor/dtor counting for memory management or something like that? The implementations would behave differently.
I keep asking because I am implementing a subset of the STL for tiny embedded systems, and I would like to be consistent with other known implementations.
Sincerely, Chris.
Construction/destruction details are independent from the STL. If the compiler does not need to call a constructor/destructor it is free to do so (as you've seen with your example). You shouldn't assume that these functions will be called at all times. As for your example, the proper way to handle memory management is to overload the new/delete operators.
Viggy
Re: Subtle differences in std::vector
Quote:
Originally Posted by
dude_1967
But is this really an implementation detail? What if someone wanted to use some ctor/dtor counting for memory management or something like that? The implementations would behave differently.
Correct. You should never write constructors / destructors /copy operations to do anything other than construct/destruct/copy, because you can't be 100% sure when the compiler might be able to optimize out those things. It's also very important that your copy operations be actual, logically equivalent copies as far as the outside world is concerned. (Binary equivalence is not required.)
In this case, the gcc implementation of vector is constructing two separate dummy objects in-place in the vector, while the VS implementation is constructing one dummy and then copying it into the two vector locations instead. (You don't output anything in the dummy's copy operations.)
Re: Subtle differences in std::vector
Thanks. All of this helped.
Sincerely, Chris.