Topic: Overhead when deriving a program-defined iterator from std::iterator


Author: unknown@this.is.invalid (Niels Dekker - no return address)
Date: Wed, 17 Jan 2007 15:40:06 GMT
Raw View
  [Thank you very much, moderator, for canceling my previous attempt!]

Pedro Lamar=E3o wrote:
> The following program outputs 1 with current cygwin gcc.
>=20
> #include <iostream>
> #include <iterator>
>=20
> struct A
> : public std::iterator<std::forward_iterator_tag, int>
> { };
>=20
> int
> main (int argc, char* argv[]) {
>     std::cout << sizeof(A) << std::endl;
>     return 0;
> }

On MSVC++ 8.0, I've seen 1, 4, and 8 as output... it appears to depend
on some settings, as mentioned by Peter Koch:

> This might well depend on your compiler and the settings you are
> compiling with. I assume your test examined release-version of the code
> together with any other options required to remove runtime checks (for
> Microsoft C++ 8.0, you need to define stuff in order to have minimal
> overhead: a "release"-build is not enough).

Actually I wasn't aware of those settings.  Apparently Microsoft's
implementation has some data members added to std::iterator (or actually
to its implementation-specific base class), in order to support their
own (optional) extension, "checked iterators".  I'm not sure if this is
strictly according to the Standard, because the Standard very explicitly
specifies how std::iterator should look like...=20

Anyway, I realize that comp.std.c++ is not the right place for more
detailed implementation-specific questions, so I've already posted my
question "Should I derive my iterator from std::iterator, on VC++ 2005?"
on microsoft.public.vc.stl

Thanks!

  Niels

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "James Kanze" <james.kanze@gmail.com>
Date: Thu, 18 Jan 2007 09:53:42 CST
Raw View
Niels Dekker - no return address wrote:

> Pedro Lamar   o wrote:
> > The following program outputs 1 with current cygwin gcc.

> > #include <iostream>
> > #include <iterator>

> > struct A
> > : public std::iterator<std::forward_iterator_tag, int>
> > { };

> > int
> > main (int argc, char* argv[]) {
> >     std::cout << sizeof(A) << std::endl;
> >     return 0;
> > }

> On MSVC++ 8.0, I've seen 1, 4, and 8 as output... it appears to depend
> on some settings, as mentioned by Peter Koch:

> > This might well depend on your compiler and the settings you are
> > compiling with. I assume your test examined release-version of the code
> > together with any other options required to remove runtime checks (for
> > Microsoft C++ 8.0, you need to define stuff in order to have minimal
> > overhead: a "release"-build is not enough).

> Actually I wasn't aware of those settings.  Apparently Microsoft's
> implementation has some data members added to std::iterator (or actually
> to its implementation-specific base class), in order to support their
> own (optional) extension, "checked iterators".

I don't think std::iterator is affected, but this is true for
all of the concrete iterators in g++ (starting with 4.0, I
believe).  With the result that linking debug code with
non-debug code results in a sure core dump.  (And the other
result that you find a lot of errors a lot faster.)

> I'm not sure if this is
> strictly according to the Standard, because the Standard very explicitly
> specifies how std::iterator should look like...

Not at all.  The standard says absolutely nothing about private
members.  An implementation could insert a char[10000] as a
private member, and recalculate the first 9999 digits of pi into
it each time you copied the iterator, and still be conform.
Useful, no, but conform, yes.

--
James Kanze (GABI Software)             email:james.kanze@gmail.com
Conseils en informatique orient   e objet/
                   Beratung in objektorientierter Datenverarbeitung
9 place S   mard, 78210 St.-Cyr-l'   cole, France, +33 (0)1 30 23 00 34


---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: unknown@this.is.invalid (Niels Dekker - no return address)
Date: Mon, 15 Jan 2007 00:03:23 GMT
Raw View
When deriving my iterator from std::iterator, I experienced a large
increase of its size!  On an implementation I'm currently using, the
following class (MyIter) has a size of 12!  While I would have expected
sizeof(MyIter) == 1!

  class MyIter:
    public std::iterator<std::bidirectional_iterator_tag, int>
  {
    // code declaring ++, etc...
    char data;
  };

Still the Draft suggests (or even recommands?) programmers to do so.
24.3.3 2:
  Typically, however, it would be easier to derive BinaryTreeIterator<T>
  from iterator<bidirectional_iterator_tag,T,ptrdiff_t,T*,T&>
24.3.3 4:
  If a C++ program wants to define a bidirectional iterator [....],
  it can do so with:
  class MyIterator :
    public iterator<bidirectional_iterator_tag, double, long, T*, T&>
(From www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2135.pdf )

Shouldn't the memory overhead caused by deriving from std::iterator be
close to zero?  If not, I guess deriving a program-defined iterator from
std::iterator might not be such a good idea...

--
Niels Dekker
http://www.xs4all.nl/~nd/dekkerware
C++ programmer at LKEB, Leiden University Medical Center

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "=?iso-8859-1?q?Pedro_Lamar=E3o?=" <pedro.lamarao@gmail.com>
Date: Mon, 15 Jan 2007 09:16:08 CST
Raw View
On 14 jan, 22:03, unkn...@this.is.invalid (Niels Dekker - no return
address) wrote:

> Shouldn't the memory overhead caused by deriving from std::iterator be
> close to zero?  If not, I guess deriving a program-defined iterator from
> std::iterator might not be such a good idea...

The following program outputs 1 with current cygwin gcc.

#include <iostream>
#include <iterator>

struct A
: public std::iterator<std::forward_iterator_tag, int>
{ };

int
main (int argc, char* argv[]) {
    std::cout << sizeof(A) << std::endl;
    return 0;
}

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: "peter koch" <peter.koch.larsen@gmail.com>
Date: Mon, 15 Jan 2007 11:06:13 CST
Raw View
Niels Dekker - no return address skrev:
> When deriving my iterator from std::iterator, I experienced a large
> increase of its size!  On an implementation I'm currently using, the
> following class (MyIter) has a size of 12!  While I would have expected
> sizeof(MyIter) == 1!
>
>   class MyIter:
>     public std::iterator<std::bidirectional_iterator_tag, int>
>   {
>     // code declaring ++, etc...
>     char data;
>   };
>
[snip draft recommendation]
>
> Shouldn't the memory overhead caused by deriving from std::iterator be
> close to zero?  If not, I guess deriving a program-defined iterator from
> std::iterator might not be such a good idea...
>
This might well depend on your compiler and the settings you are
compiling with. I assume your test examined release-version of the code
together with any other options required to remove runtime checks (for
Microsoft C++ 8.0, you need to define stuff in order to have minimal
overhead: a "release"-build is not enough).

/Peter

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]





Author: Carl Barron <cbarron413@adelphia.net>
Date: Tue, 16 Jan 2007 11:07:47 CST
Raw View
In article <1168867122.162410.191450@a75g2000cwd.googlegroups.com>,
Pedro Lamar   o <pedro.lamarao@gmail.com> wrote:

> On 14 jan, 22:03, unkn...@this.is.invalid (Niels Dekker - no return
> address) wrote:
>
> > Shouldn't the memory overhead caused by deriving from std::iterator be
> > close to zero?  If not, I guess deriving a program-defined iterator from
> > std::iterator might not be such a good idea...
>
> The following program outputs 1 with current cygwin gcc.
>
> #include <iostream>
> #include <iterator>
>
> struct A
> : public std::iterator<std::forward_iterator_tag, int>
> { };
>
> int
> main (int argc, char* argv[]) {
>     std::cout << sizeof(A) << std::endl;
>     return 0;
> }
>
    sizeof struct's must be > 0.  If the compiler is smart enough
struct B :public std::iterator<std::forward_iterator_tag,int>
{
   char c;
};

sizeof(B) == size(A)  most likely.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.comeaucomputing.com/csc/faq.html                      ]