Thursday, October 2, 2008

26 new messages in 5 topics - digest

comp.lang.c++
http://groups.google.com/group/comp.lang.c++?hl=en

comp.lang.c++@googlegroups.com

Today's topics:

* STL container question - 13 messages, 6 authors
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/d2af39d060636197?hl=en
* throwing dtors... - 2 messages, 2 authors
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/ec97ab562016d016?hl=en
* The need of Unicode types in C++0x - 4 messages, 3 authors
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/56ed90f231762d03?hl=en
* Strange behaviour - 3 messages, 2 authors
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/79912eac71e25344?hl=en
* Strange behaviour (corrected) - 4 messages, 2 authors
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/05444e0f6a776b9e?hl=en

==============================================================================
TOPIC: STL container question
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/d2af39d060636197?hl=en
==============================================================================

== 1 of 13 ==
Date: Thurs, Oct 2 2008 8:54 am
From: Ioannis Vranos


Lars Tetzlaff wrote:
> Ioannis Vranos schrieb:
>> The program had a serious bug.
>>
>>
>> corrected:
>>
>>
>> Ioannis Vranos wrote:
>>> Hendrik Schober wrote:
>>>> Ioannis Vranos wrote:
>>>>> [...]
>>>>> We must think generally. In general, sorting a list is faster than
>>>>> sorting a vector, because the list sorting does not involve the
>>>>> construction or destruction of any object.
>>>>>
>>>>> Regarding ints, I think sorting a vector of ints and as list of
>>>>> ints, both have about the same efficiency.
>>>> Why don't you just measure before you doubt the statements
>>>> of those who already went and did this?
>>>>
>>>> On my platform, this
>>>
>>> [ Non-portable code...]
>>>
>>>
>>>
>>>> and thus again disagrees with you.
>>>>
>>>> Eagerly awaiting your counter example,
>>
>> #include <iostream>
>> #include <ctime>
>> #include <vector>
>> #include <list>
>> #include <cstddef>
>> #include <algorithm>
>>
>>
>> class SomeClass
>> {
>> typedef std::vector<int> TypeVector;
>>
>> TypeVector vec;
>>
>> enum { VectorSize= 1000 };
>>
>> public:
>>
>> SomeClass();
>>
>> bool operator<(const SomeClass &argSomeClass) const
>> {
>> return vec[0]< argSomeClass.vec[0];
>> }
>> };
>>
>>
>>
>>
>>
>> int main()
>> {
>> using namespace std;
>>
>> srand(time(0));
>>
>> const size_t SIZE=10000;
>>
>> typedef vector<SomeClass> Vector;
>> typedef list<SomeClass> List;
>>
>>
>> cout<< "\nCreating vector with "<< SIZE<< " elements..."<< flush;
>> Vector vec(SIZE);
>>
>> cout<<" Done!\n\n"<< flush;
>>
>> ===> List lis;
>>
>>
>> cout<< "Filling list with vector elements..."<< flush;
>>
>> for(Vector::size_type i= 0; i< vec.size(); ++i)
>> lis.push_back(vec[i]);
>>
>> cout<< " Done!\n\n"<< flush;
>>
>>
>> clock_t timeBeginVector, timeEndVector, timeBeginList, timeEndList;
>>
>>
>> cout<< "Timing the sorting of the vector..."<< flush;
>>
>> timeBeginVector= clock();
>>
>> sort(vec.begin(), vec.end());
>>
>> timeEndVector= clock();
>>
>> cout<< " Done!\n\n"<< flush;
>>
>>
>> cout<< "Timing the sorting of the list..."<< flush;
>>
>> timeBeginList= clock();
>>
>> lis.sort();
>>
>> timeEndList= clock();
>>
>>
>> cout<< " Done!\n\n"<< flush;
>>
>>
>> cout<< "The sorting of the vector took "
>> << static_cast<double>((timeEndVector- timeBeginVector))/
>> CLOCKS_PER_SEC
>> << " seconds\n\n";
>>
>> cout<< "The sorting of the list took "
>> << static_cast<double>((timeEndList- timeBeginList))/
>> CLOCKS_PER_SEC
>> << " seconds\n\n";
>> }
>>
>>
>>
>> SomeClass::SomeClass():vec(VectorSize)
>> {
>> using namespace std;
>>
>> for(TypeVector::size_type i= 0; i< vec.size(); ++i)
>> vec[i]= rand();
>>
>> sort(vec.begin(), vec.end());
>> }
>
> This program doesn't sort at all, because the vec is initialized with
> one constant!


? Yes it is initalised with its number of elements, which are SomeClass
objects created with their default constructor.


> Change the list filling code to
>
> for(Vector::size_type i= 0; i< vec.size(); ++i) {
> vec[i]= SomeClass();
> lis.push_back(vec[i]);
> }


Why?

== 2 of 13 ==
Date: Thurs, Oct 2 2008 9:14 am
From: Lars Tetzlaff


Ioannis Vranos schrieb:
> Lars Tetzlaff wrote:
>> Ioannis Vranos schrieb:
>>> The program had a serious bug.
>>>
>>>
>>> corrected:
>>>
>>>
>>> Ioannis Vranos wrote:
>>>> Hendrik Schober wrote:
>>>>> Ioannis Vranos wrote:
>>>>>> [...]
>>>>>> We must think generally. In general, sorting a list is faster than
>>>>>> sorting a vector, because the list sorting does not involve the
>>>>>> construction or destruction of any object.
>>>>>>
>>>>>> Regarding ints, I think sorting a vector of ints and as list of
>>>>>> ints, both have about the same efficiency.
>>>>> Why don't you just measure before you doubt the statements
>>>>> of those who already went and did this?
>>>>>
>>>>> On my platform, this
>>>>
>>>> [ Non-portable code...]
>>>>
>>>>
>>>>
>>>>> and thus again disagrees with you.
>>>>>
>>>>> Eagerly awaiting your counter example,
>>>
>>> #include <iostream>
>>> #include <ctime>
>>> #include <vector>
>>> #include <list>
>>> #include <cstddef>
>>> #include <algorithm>
>>>
>>>
>>> class SomeClass
>>> {
>>> typedef std::vector<int> TypeVector;
>>>
>>> TypeVector vec;
>>>
>>> enum { VectorSize= 1000 };
>>>
>>> public:
>>>
>>> SomeClass();
>>>
>>> bool operator<(const SomeClass &argSomeClass) const
>>> {
>>> return vec[0]< argSomeClass.vec[0];
>>> }
>>> };
>>>
>>>
>>>
>>>
>>>
>>> int main()
>>> {
>>> using namespace std;
>>>
>>> srand(time(0));
>>>
>>> const size_t SIZE=10000;
>>>
>>> typedef vector<SomeClass> Vector;
>>> typedef list<SomeClass> List;
>>>
>>>
>>> cout<< "\nCreating vector with "<< SIZE<< " elements..."<< flush;
>>> Vector vec(SIZE);
>>>
>>> cout<<" Done!\n\n"<< flush;
>>>
>>> ===> List lis;
>>>
>>>
>>> cout<< "Filling list with vector elements..."<< flush;
>>>
>>> for(Vector::size_type i= 0; i< vec.size(); ++i)
>>> lis.push_back(vec[i]);
>>>
>>> cout<< " Done!\n\n"<< flush;
>>>
>>>
>>> clock_t timeBeginVector, timeEndVector, timeBeginList, timeEndList;
>>>
>>>
>>> cout<< "Timing the sorting of the vector..."<< flush;
>>>
>>> timeBeginVector= clock();
>>>
>>> sort(vec.begin(), vec.end());
>>>
>>> timeEndVector= clock();
>>>
>>> cout<< " Done!\n\n"<< flush;
>>>
>>>
>>> cout<< "Timing the sorting of the list..."<< flush;
>>>
>>> timeBeginList= clock();
>>>
>>> lis.sort();
>>>
>>> timeEndList= clock();
>>>
>>>
>>> cout<< " Done!\n\n"<< flush;
>>>
>>>
>>> cout<< "The sorting of the vector took "
>>> << static_cast<double>((timeEndVector- timeBeginVector))/
>>> CLOCKS_PER_SEC
>>> << " seconds\n\n";
>>>
>>> cout<< "The sorting of the list took "
>>> << static_cast<double>((timeEndList- timeBeginList))/
>>> CLOCKS_PER_SEC
>>> << " seconds\n\n";
>>> }
>>>
>>>
>>>
>>> SomeClass::SomeClass():vec(VectorSize)
>>> {
>>> using namespace std;
>>>
>>> for(TypeVector::size_type i= 0; i< vec.size(); ++i)
>>> vec[i]= rand();
>>>
>>> sort(vec.begin(), vec.end());
>>> }
>>
>> This program doesn't sort at all, because the vec is initialized with
>> one constant!
>
>
> ? Yes it is initalised with its number of elements, which are SomeClass
> objects created with their default constructor.
>
>

On my system all values are equal. The constructor is only called once!
The other elements are initialized with a copy of this SomeClass object!

Don't know what the standard says about this ...

>> Change the list filling code to
>>
>> for(Vector::size_type i= 0; i< vec.size(); ++i) {
>> vec[i]= SomeClass();
>> lis.push_back(vec[i]);
>> }
>
>
> Why?

To get distinct elements. See above.


Lars

== 3 of 13 ==
Date: Thurs, Oct 2 2008 9:25 am
From: Ioannis Vranos


Lars Tetzlaff wrote:
>> corrected:
>
>> #include <iostream>
>> #include <ctime>
>> #include <vector>
>> #include <list>
>> #include <cstddef>
>> #include <algorithm>
>>
>>
>> class SomeClass
>> {
>> typedef std::vector<int> TypeVector;
>>
>> TypeVector vec;
>>
>> enum { VectorSize= 1000 };
>>
>> public:
>>
>> SomeClass();
>>
>> bool operator<(const SomeClass &argSomeClass) const
>> {
>> return vec[0]< argSomeClass.vec[0];
>> }
>> };
>>
>>
>>
>>
>>
>> int main()
>> {
>> using namespace std;
>>
>> srand(time(0));
>>
>> const size_t SIZE=10000;
>>
>> typedef vector<SomeClass> Vector;
>> typedef list<SomeClass> List;
>>
>>
>> cout<< "\nCreating vector with "<< SIZE<< " elements..."<< flush;
>> Vector vec(SIZE);
>>
>> cout<<" Done!\n\n"<< flush;
>>
>> ===> List lis;
>>
>>
>> cout<< "Filling list with vector elements..."<< flush;
>>
>> for(Vector::size_type i= 0; i< vec.size(); ++i)
>> lis.push_back(vec[i]);
>>
>> cout<< " Done!\n\n"<< flush;
>>
>>
>> clock_t timeBeginVector, timeEndVector, timeBeginList, timeEndList;
>>
>>
>> cout<< "Timing the sorting of the vector..."<< flush;
>>
>> timeBeginVector= clock();
>>
>> sort(vec.begin(), vec.end());
>>
>> timeEndVector= clock();
>>
>> cout<< " Done!\n\n"<< flush;
>>
>>
>> cout<< "Timing the sorting of the list..."<< flush;
>>
>> timeBeginList= clock();
>>
>> lis.sort();
>>
>> timeEndList= clock();
>>
>>
>> cout<< " Done!\n\n"<< flush;
>>
>>
>> cout<< "The sorting of the vector took "
>> << static_cast<double>((timeEndVector- timeBeginVector))/
>> CLOCKS_PER_SEC
>> << " seconds\n\n";
>>
>> cout<< "The sorting of the list took "
>> << static_cast<double>((timeEndList- timeBeginList))/
>> CLOCKS_PER_SEC
>> << " seconds\n\n";
>> }
>>
>>
>>
>> SomeClass::SomeClass():vec(VectorSize)
>> {
>> using namespace std;
>>
>> for(TypeVector::size_type i= 0; i< vec.size(); ++i)
>> vec[i]= rand();
>>
>> sort(vec.begin(), vec.end());
>> }
>
>
>> This program doesn't sort at all, because the vec is initialized with
>> one constant!
>>
>> ? Yes it is initalised with its number of elements, which are SomeClass
>> objects created with their default constructor.
>>
>>
>
> On my system all values are equal. The constructor is only called once!
> The other elements are initialized with a copy of this SomeClass object!


There are two vecs in the code. Please be more specific, which are you
referring to?

== 4 of 13 ==
Date: Thurs, Oct 2 2008 9:29 am
From: Lars Tetzlaff


Ioannis Vranos schrieb:
> Lars Tetzlaff wrote:
>>> corrected:
>>
>>> #include <iostream>
>>> #include <ctime>
>>> #include <vector>
>>> #include <list>
>>> #include <cstddef>
>>> #include <algorithm>
>>>
>>>
>>> class SomeClass
>>> {
>>> typedef std::vector<int> TypeVector;
>>>
>>> TypeVector vec;
>>>
>>> enum { VectorSize= 1000 };
>>>
>>> public:
>>>
>>> SomeClass();
>>>
>>> bool operator<(const SomeClass &argSomeClass) const
>>> {
>>> return vec[0]< argSomeClass.vec[0];
>>> }
>>> };
>>>
>>>
>>>
>>>
>>>
>>> int main()
>>> {
>>> using namespace std;
>>>
>>> srand(time(0));
>>>
>>> const size_t SIZE=10000;
>>>
>>> typedef vector<SomeClass> Vector;
>>> typedef list<SomeClass> List;
>>>
>>>
>>> cout<< "\nCreating vector with "<< SIZE<< " elements..."<< flush;
>>> Vector vec(SIZE);
>>>
>>> cout<<" Done!\n\n"<< flush;
>>>
>>> ===> List lis;
>>>
>>>
>>> cout<< "Filling list with vector elements..."<< flush;
>>>
>>> for(Vector::size_type i= 0; i< vec.size(); ++i)
>>> lis.push_back(vec[i]);
>>>
>>> cout<< " Done!\n\n"<< flush;
>>>
>>>
>>> clock_t timeBeginVector, timeEndVector, timeBeginList, timeEndList;
>>>
>>>
>>> cout<< "Timing the sorting of the vector..."<< flush;
>>>
>>> timeBeginVector= clock();
>>>
>>> sort(vec.begin(), vec.end());
>>>
>>> timeEndVector= clock();
>>>
>>> cout<< " Done!\n\n"<< flush;
>>>
>>>
>>> cout<< "Timing the sorting of the list..."<< flush;
>>>
>>> timeBeginList= clock();
>>>
>>> lis.sort();
>>>
>>> timeEndList= clock();
>>>
>>>
>>> cout<< " Done!\n\n"<< flush;
>>>
>>>
>>> cout<< "The sorting of the vector took "
>>> << static_cast<double>((timeEndVector- timeBeginVector))/
>>> CLOCKS_PER_SEC
>>> << " seconds\n\n";
>>>
>>> cout<< "The sorting of the list took "
>>> << static_cast<double>((timeEndList- timeBeginList))/
>>> CLOCKS_PER_SEC
>>> << " seconds\n\n";
>>> }
>>>
>>>
>>>
>>> SomeClass::SomeClass():vec(VectorSize)
>>> {
>>> using namespace std;
>>>
>>> for(TypeVector::size_type i= 0; i< vec.size(); ++i)
>>> vec[i]= rand();
>>>
>>> sort(vec.begin(), vec.end());
>>> }
>>
>>
>>> This program doesn't sort at all, because the vec is initialized with
>>> one constant!
>>>
>>> ? Yes it is initalised with its number of elements, which are SomeClass
>>> objects created with their default constructor.
>>>
>>>
>>
>> On my system all values are equal. The constructor is only called once!
>> The other elements are initialized with a copy of this SomeClass object!
>
>
> There are two vecs in the code. Please be more specific, which are you
> referring to?

Vector vec(SIZE); in main.

Lars

== 5 of 13 ==
Date: Thurs, Oct 2 2008 10:01 am
From: Ioannis Vranos


Lars Tetzlaff wrote:
>>
>> There are two vecs in the code. Please be more specific, which are you
>> referring to?
>
> Vector vec(SIZE); in main.


Already spotted the strange behaviour and posted a new message with the
subject "Strange behaviour".

== 6 of 13 ==
Date: Thurs, Oct 2 2008 10:09 am
From: Rolf Magnus


Ioannis Vranos wrote:

> Hendrik Schober wrote:
>> Ioannis Vranos wrote:
>>> The program had a serious bug.
>>>
>>>
>>> corrected:
>>> [...]
>>
>> Creating vector with 100000 elements... Done!
>> Filling list with vector elements... Done!
>> Timing the sorting of the vector... Done!
>> Timing the sorting of the list... Done!
>> The sorting of the vector took 0.015 seconds
>> The sorting of the list took 0.437 seconds
>
>
>
> Again, increase the number of const size_t SIZE so as to exceed 1-2
> seconds for the sorting of one container, and then post your results.

What does your example have to do with the OP's question? The OP has one int
as member, while in your code, each element contains a vector of 1000 ints
instead. If this proves anything, then that you can construct a situation
where a list is faster than a vector. Unfortunately, that situation has
nothing to do with the OP's question.

== 7 of 13 ==
Date: Thurs, Oct 2 2008 10:34 am
From: "Chris M. Thomasson"


"Ioannis Vranos" <ivranos@no.spam.nospamfreemail.gr> wrote in message
news:gc2qk2$26om$1@ulysses.noc.ntua.gr...
> Chris M. Thomasson wrote:
>>
>>
>> Doesn't a swap sort of imply a copy of "something"?
>>
>> struct object {
>> int x;
>> };
>>
>> object objs[2] = { { 0 }, { 1 } };
>>
>> How do you swap `obj[0]' with `obj[1]' without copying "something"?
>>
>
>
> A vector::swap() can be a shallow swap. For example if a vector is
> implemented as a pointer pointing to an array on the free store, swap
> could just swap the pointer values, without interfering with the contents.

My point was that "something" is copied; in this case a pointer value.
However, in this case, that statement would be a ridiculous nit-pick!

;^)

== 8 of 13 ==
Date: Thurs, Oct 2 2008 10:38 am
From: "Chris M. Thomasson"


"Chris M. Thomasson" <no@spam.invalid> wrote in message
news:Nw7Fk.13201$ex3.11405@newsfe02.iad...
> "Ioannis Vranos" <ivranos@no.spam.nospamfreemail.gr> wrote in message
> news:gc2qk2$26om$1@ulysses.noc.ntua.gr...
>> Chris M. Thomasson wrote:
>>>
>>>
>>> Doesn't a swap sort of imply a copy of "something"?
>>>
>>> struct object {
>>> int x;
>>> };
>>>
>>> object objs[2] = { { 0 }, { 1 } };
>>>
>>> How do you swap `obj[0]' with `obj[1]' without copying "something"?
>>>
>>
>>
>> A vector::swap() can be a shallow swap. For example if a vector is
>> implemented as a pointer pointing to an array on the free store, swap
>> could just swap the pointer values, without interfering with the
>> contents.
>
> My point was that "something" is copied; in this case a pointer value.
> However, in this case, that statement would be a ridiculous nit-pick!
>
> ;^)

Anyway, I this was about sorting vectors... AFAICT, this implies some
swapping of the contents of slots in the array, and swapping implies
"something" is copied. If its a pointer value, so be it. If not, well, then
things can start to get expensive. The sort and swap impl needs to be very
highly optimized indeed.

== 9 of 13 ==
Date: Thurs, Oct 2 2008 10:39 am
From: "Chris M. Thomasson"


"Chris M. Thomasson" <no@spam.invalid> wrote in message
news:bA7Fk.13202$ex3.3089@newsfe02.iad...
> "Chris M. Thomasson" <no@spam.invalid> wrote in message
> news:Nw7Fk.13201$ex3.11405@newsfe02.iad...
>> "Ioannis Vranos" <ivranos@no.spam.nospamfreemail.gr> wrote in message
>> news:gc2qk2$26om$1@ulysses.noc.ntua.gr...
>>> Chris M. Thomasson wrote:
>>>>
>>>>
>>>> Doesn't a swap sort of imply a copy of "something"?
>>>>
>>>> struct object {
>>>> int x;
>>>> };
>>>>
>>>> object objs[2] = { { 0 }, { 1 } };
>>>>
>>>> How do you swap `obj[0]' with `obj[1]' without copying "something"?
>>>>
>>>
>>>
>>> A vector::swap() can be a shallow swap. For example if a vector is
>>> implemented as a pointer pointing to an array on the free store, swap
>>> could just swap the pointer values, without interfering with the
>>> contents.
>>
>> My point was that "something" is copied; in this case a pointer value.
>> However, in this case, that statement would be a ridiculous nit-pick!
>>
>> ;^)
>
> Anyway, I this was about sorting vectors...
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Anyway, I _thought_ this was about sorting vectors...


ARGH!


> AFAICT, this implies some swapping of the contents of slots in the array,
> and swapping implies "something" is copied. If its a pointer value, so be
> it. If not, well, then things can start to get expensive. The sort and
> swap impl needs to be very highly optimized indeed.

== 10 of 13 ==
Date: Thurs, Oct 2 2008 10:43 am
From: "Chris M. Thomasson"


"Jerry Coffin" <jcoffin@taeus.com> wrote in message
news:MPG.234e90945d533ff9989697@news.sunsite.dk...
> In article <aeb09adf-92fc-45ce-aa7f-
> 80f4ba2e6e3d@l62g2000hse.googlegroups.com>, maxim.yegorushkin@gmail.com
> says...
>
> [ ... ]
>
>> You are correct that as lists do not provide random-access iterators
>> quicksort can not be used.
>
> Actually, that's not true. It's entirely possible to implement a
> quicksort on a linked list. You can't (efficiently) use a median-of-
> three (or whatever) pivot selection, but the quicksort itself has no
> need for random-access iteration.

You can use quick-sort on a skip-list where one of the skip-links points to
the middle of the list, or some other pivot.


>> Instead, lists are normally sorted using merge sort.
>
> This, however, is true. Even though you _can_ use quicksort on a linked
> list, the potential gains from doing so are much smaller than the
> potential losses.
>
>> Merge sort has better worst-case performance than
>> quicksort. The drawback of merge sort is that it normally requires
>> extra memory, whereas quicksort does not.
>
> When applied to arrays/vectors, that's true. For a linked list, they
> both require essentially the same extra memory.
>
> --
> Later,
> Jerry.
>
> The universe is a figment of its own imagination.

== 11 of 13 ==
Date: Thurs, Oct 2 2008 10:49 am
From: Erik Wikström


On 2008-10-02 16:11, Victor Bazarov wrote:
> Ioannis Vranos wrote:
>> Ioannis Vranos wrote:
>>>
>>>> The program had a serious bug.
>>>
>> > [...]
>> >
>> >
>>> And my results:
>>>
>>>
>>> 1. const size_t SIZE= 90000;
>>>
>>>
>>> john@john-desktop:~/Projects/src$ ./foobar_cpp
>>>
>>> Creating vector with 90000 elements... Done!
>>>
>>> Filling list with vector elements... Done!
>>>
>>> Timing the sorting of the vector... Done!
>>>
>>> Timing the sorting of the list... Done!
>>>
>>> The sorting of the vector took 24.79 seconds
>>>
>>> The sorting of the list took 0.1 seconds

I managed to duplicate your results once, but only once. Despite
numerous tries your code consistently shows the vector being at least an
order of magnitude faster. Make sure your are not running other CPU-
intensive applications while running the test.

> The system I tested on is DELL T7400 (dual Intel Xeon quad core), Vista
> Ultimate 64, Visual C++ 2008 sp1, 4 gigs of RAM. Since no parallelizing
> is done in your program, the number of cores doesn't matter, but the CPU
> is faster, and while I would love to try it on a 16-gigabyte machine or
> better, I don't have access to one. My machine is what our clients are
> getting, so the results stand. You're free to speculate what makes it
> so *bad* on your machine, but I'd seriously think about switching to a
> real OS and a real compiler, if I got such bad results as you do.

Long since I last heard anyone calling Linux and gcc toy products. :-)

--
Erik Wikström

== 12 of 13 ==
Date: Thurs, Oct 2 2008 10:55 am
From: Victor Bazarov


Ioannis Vranos wrote:
> The program had a serious bug.
>
>
> corrected:
>
> [..]

OK, as it was determined, your compiler has a bug (that makes it invoke
the default c-tor for all elements of a vector constructed with only the
size given. I've added a copy constructor that does exactly the same
thing as the default constructor and finally got your results. A vector
of large objects with random values takes longer to sort than a list of
large objects with similarly random values. Significantly longer. Your
theory is confirmed, I suppose.

Now, it has really nothing to do with the OP's problem, but still...

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

== 13 of 13 ==
Date: Thurs, Oct 2 2008 10:57 am
From: Victor Bazarov


Erik Wikström wrote:
> On 2008-10-02 16:11, Victor Bazarov wrote:
>> [..] You're free to speculate what makes it
>> so *bad* on your machine, but I'd seriously think about switching to a
>> real OS and a real compiler, if I got such bad results as you do.
>
> Long since I last heard anyone calling Linux and gcc toy products. :-)

I didn't call them toy products, either.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


==============================================================================
TOPIC: throwing dtors...
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/ec97ab562016d016?hl=en
==============================================================================

== 1 of 2 ==
Date: Thurs, Oct 2 2008 8:55 am
From: ytrembla@nyx.nyx.net (Yannick Tremblay)


In article <gq4Fk.22242$YN5.20731@newsfe03.iad>,
Chris M. Thomasson <no@spam.invalid> wrote:
>
>Humm, perhaps something like:
>
>class file {
>public:
> struct error_code {
> enum value {
> succeeded = 0x0,
> failed = 0x1,
OK

> bad_descriptor = failed | 0x2,
> exceeds_offset = failed | 0x4,
> process_orphaned = failed | 0x8,
> no_free_space = failed | 0x10,
> pipe_not_for_reading = failed | 0x20,
> non_existing_device = failed | 0x40,
All fatal failures.

> already_closed = failed | 0x80,
Is this really a failure? The file is correctly
closed.

> unknown = failed | 0x100
Still a fatal failure.

>
>That way you can combine several error codes in a single value; sometimes
>that ability might be fairly "useful" and/or convenient. However, IMVHO, how
>does this improve on my example with fine-grain exceptions? Do C++
>programmers tolerate having to examine return values for error-codes? I
>think some of them would be fine with a simple boolean in certain cases, but
>more than that would perhaps sound too C`ish?

Hmm, complexity, complexity. Is that complexity necessary? Good C++
programmers like all other good programmer tolerate complexity when
complexity is needed. However, typically, the good C++ programmer is
trained in the concept of implementation hiding where unecessary
complexity is hidden away from the client code under a simpler to use
interface. If the complexity is needed for the client then the
complexity must be exposed. However, if it is not needed, it should
not be exposed.

Large application programming is in large part an exercise in
complexity management. If you try to build a house with grains of
sands, you are up against it. Bricks are much much productive.

So back in the real world :-)
Typically, one file close failure, three things can be done:
1- Try again
2- Give up and continue anyway
3- Kill the application

In very rare case, it might be possible to delete some files to free
disk space but this is rarely a possible action.

In all these cases, logging is likely to be desirable.

1- Try again can quite possibly be encapsulated in a more advanced
close function if the client doesn't have real time requirements. So
this complexity often needs not be exposed to the client.

2 or 3 are likely to be the higher level logic reaction for an
irrecoverable error regardless of the cause fo the error. If you try
to copy a file, it is irrelevant if it failed due to out of disk space
or non-existing device. It failed. In a server, you might raise an
alarm and keep going in the hope that maybe next time it will work
(maybe logrotate will have run by then or the remote device will be
back online), in another case you just exit, most probably regardless
of the cause.

The logging of the cause of the error can very easily be encapsulate
(or if exceptions are used, what() can give you a useful string).

So in my opinion, in a large number of cases where multiples unique
error codes are used, a simpler interface:

bool DoItAndTryToRecoverIfPossibleElseLogAndReturnFailure()

is sufficient. Now in your particular case, it might not be
sufficient but make sure that the complexity is really needed because
if the client code has to deal with a more complex interface, it is
more likely to have bug and will take longer to develop.

Yannick


== 2 of 2 ==
Date: Thurs, Oct 2 2008 10:32 am
From: "Chris M. Thomasson"


"Andre Kostur" <andre@kostur.net> wrote in message
news:Xns9B2B5A829D894nntpspamkosutrnet@209.135.99.21...
> "Chris M. Thomasson" <no@spam.invalid> wrote in
> news:X5_Ek.12946$ex3.3200@newsfe02.iad:
>
>> "anon" <anon@no.invalid> wrote in message
>> news:gc1n78$kks$1@news01.versatel.de...
>>> Chris M. Thomasson wrote:
>>>> Is it every appropriate to throw in a dtor? I am thinking about a
>>>> simple example of a wrapper around a POSIX file...
[...]
>> Any thoughts?
>>
>
> Yep, you're not using exceptions appropriately. What should be
> happening is your loop around fclose should be in the destructor itself.

Right. I would only loop on `EINTR' in dtor, and perhaps have a bounded loop
on `EAGAIN' with a slight delay in between (e.g., sched_yield() or
something). I just would clearly document that if the user does not
explicitly close the file by invoking `file::close()' member-function then
the dtor will attempt to close, but if it fails, then no error condition
will be reported to the user at the time of dtor call.


> By throwing an exception out of the destructor you are effectively
> saying that the object was unable to be destroyed. Now you're in for a
> whole world of hurt. How can you possibly recover from that? The
> object is already on its way out of scope, and now you can't destroy it.
> You can't abort the object going out of scope. Really, if the caller
> really was ready to handle errors from fclose, then they should be using
> whatever method of the file class that just does fclose before allowing
> the object to fall out of scope.
>
> Additionally a whole different world of hurt happens is you have an
> array of these things. Let's assume an array of 10 of them. Also let's
> assume that object #7 throws an exception during construction. So the
> program dutifully destroys all of the previous objects that it had
> previously fully constructed. And object #3 throws an exception during
> its destructor. Now you have 2 active exceptions running around.
> That's a short trip to a terminated program. You can't catch it. This
> is probably the best example of why allowing exceptions to propogate out
> of destructors is a Bad Thing.

I have concluded that something like the following would work:

http://groups.google.com/group/comp.lang.c++/msg/d40f3efc3e5ee5ed

The `file::~file()' is decorated with throw(), and does not throw anything.
If the user wants to be 100% sure that `fclose()' succeeds, then she/he
needs to call `file::close()' before the object gets destroyed. Now, this
member-function can throw from a fine-grain exception hierarchy if
`fclose()' bites the dust, and the user can catch specific error conditions
and act accordingly. This seems workable to me... What do you think?


==============================================================================
TOPIC: The need of Unicode types in C++0x
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/56ed90f231762d03?hl=en
==============================================================================

== 1 of 4 ==
Date: Thurs, Oct 2 2008 9:11 am
From: Ioannis Vranos


Yannick Tremblay wrote:
>
>>
>> I do not know much about encodings, only the necessary for me stuff, but
>> the question does not sound reasonable for me.
>>
>> If that system supports Unicode as a system-specific type, why can't
>> wchar_t be made wide enough as that system-specific Unicode type, in
>> that system?
>
> There is no system that support "Unicode". you should go to:
> http://www.unicode.org/standard/WhatIsUnicode.html
>
> Unicode is basically a catalog of glyphs and associated numeric value.
> for a computer system, it only make sense to be precise and talk about
> UTF8, UTF16 or UTF32.
> http://www.unicode.org/faq/utf_bom.html

I agree so far.


> A "Unicode" locale makes no sense because the
> locale represent much more than simply the character encoding that is
> being used.
> http://www.unicode.org/reports/tr35/#Locale


True, but I think Unicode locales could be implemented for characters
only, leaving the rest unchanged (as they are).


For example:


locale::global(locale("english"));


wcin.imbue(locale("UTF16"));
wcout.imbue(locale("UTF16"));


would change only the character set, keeping the rest of the locale
settings as they are either they were previously defined or they are the
default ones.

== 2 of 4 ==
Date: Thurs, Oct 2 2008 9:36 am
From: Pete Becker


On 2008-10-02 06:34:25 -0400, Ioannis Vranos
<ivranos@no.spam.nospamfreemail.gr> said:

> Pete Becker wrote:
>> On 2008-10-01 12:57:27 -0400, Ioannis Vranos
>> <ivranos@no.spam.nospamfreemail.gr> said:
>>
>>>
>>> If that system supports Unicode as a system-specific type, why can't
>>> wchar_t be made wide enough as that system-specific Unicode type, in
>>> that system?
>>
>> It can be. But the language definition doesn't require it to be, and
>> with many implementations it's not
>
>
> C++03 mentions:
>
>
> "Type wchar_t is a distinct type whose values can represent distinct
> codes for all members of the *largest* extended character set specified
> among the supported *locales* (22.1.1). Type wchar_t shall have the same
> size, signedness, and alignment requirements (3.9) as one of the other
> integral types, called its underlying type".

There's nothing there that requires wchar_t to be large enough to hold
Unicode code points. Certainly if an implementation supports a Unicode
local, wchar_t has to be large enough to handle those characters. But
the language definition doesn't require Unicode locales.

--
Pete
Roundhouse Consulting, Ltd. (www.versatilecoding.com) Author of "The
Standard C++ Library Extensions: a Tutorial and Reference
(www.petebecker.com/tr1book)

== 3 of 4 ==
Date: Thurs, Oct 2 2008 10:11 am
From: Ioannis Vranos


Pete Becker wrote:
> On 2008-10-02 06:34:25 -0400, Ioannis Vranos
> <ivranos@no.spam.nospamfreemail.gr> said:
>
>> Pete Becker wrote:
>>> On 2008-10-01 12:57:27 -0400, Ioannis Vranos
>>> <ivranos@no.spam.nospamfreemail.gr> said:
>>>
>>>>
>>>> If that system supports Unicode as a system-specific type, why can't
>>>> wchar_t be made wide enough as that system-specific Unicode type, in
>>>> that system?
>>>
>>> It can be. But the language definition doesn't require it to be, and
>>> with many implementations it's not
>>
>>
>> C++03 mentions:
>>
>>
>> "Type wchar_t is a distinct type whose values can represent distinct
>> codes for all members of the *largest* extended character set
>> specified among the supported *locales* (22.1.1). Type wchar_t shall
>> have the same
>> size, signedness, and alignment requirements (3.9) as one of the other
>> integral types, called its underlying type".
>
> There's nothing there that requires wchar_t to be large enough to hold
> Unicode code points. Certainly if an implementation supports a Unicode
> local, wchar_t has to be large enough to handle those characters. But
> the language definition doesn't require Unicode locales.


Yes, I am talking about the upcoming Unicode character types in C++0x,
in comparison with the Unicode locales alternative.

== 4 of 4 ==
Date: Thurs, Oct 2 2008 10:27 am
From: Erik Wikström


On 2008-10-02 12:26, Ioannis Vranos wrote:
> Erik Wikström wrote:
>>
>> Because it has been to narrow for 5 to 10 years and the compiler vendor
>> does not want to take any chances with backward compatibility,
>
>
> How will it break backward compatibility, if the size of whcar_t changes?

Because the user expects to be able to pack 5 wchar_t into a network-
message of a fixed size, or read a few characters from a specific
position in a binary file. Or any number of reasons where someone have
made assumptions about the size of wchar_t.

--
Erik Wikström


==============================================================================
TOPIC: Strange behaviour
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/79912eac71e25344?hl=en
==============================================================================

== 1 of 3 ==
Date: Thurs, Oct 2 2008 10:00 am
From: Ioannis Vranos


The code:

#include <iostream>
#include <ctime>
#include <vector>
#include <cstddef>


struct SomeClass
{
typedef std::vector<int> TypeVector;

TypeVector vec;

enum { VectorSize= 10 };

public:

SomeClass();
};

SomeClass::SomeClass():vec(VectorSize)
{
using namespace std;

srand(0);

for(TypeVector::size_type i= 0; i< vec.size(); ++i)
{
vec[i]= rand();

cout<<vec[i]<<"\t";
}

cout<<"\n\n";
}

int main()
{
using namespace std;

const size_t SIZE=10;

typedef vector<SomeClass> Vector;

cout<< "\nCreating vector with "<< SIZE<< " SomeClass objects..."<<
endl;
Vector vec(SIZE);

}

in my system produces:

john@john-desktop:~/Projects/Other/anjuta1/src$ ./foobar_cpp

Creating vector with 10 SomeClass objects...
1804289383 846930886 1681692777 1714636915
1957747793 424238335 719885386 1649760492
596516649 1189641421

john@john-desktop:~/Projects/Other/anjuta1/src$


(10 values) instead of 100 values. Is it a compiler defect, or am I
missing something?

== 2 of 3 ==
Date: Thurs, Oct 2 2008 10:05 am
From: Ioannis Vranos


The code:

#include <iostream>
#include <ctime>
#include <vector>
#include <cstddef>


struct SomeClass
{
typedef std::vector<int> TypeVector;

TypeVector vec;

enum { VectorSize= 10 };

public:

SomeClass();
};

SomeClass::SomeClass():vec(VectorSize)
{
using namespace std;

srand(time(0));

for(TypeVector::size_type i= 0; i< vec.size(); ++i)
{
vec[i]= rand();

cout<<vec[i]<<" ";
}

cout<<"\n\n";
}

int main()
{
using namespace std;

const size_t SIZE=10;

typedef vector<SomeClass> Vector;

cout<< "\nCreating vector with "<< SIZE<< " SomeClass objects..."<<
endl;
Vector vec(SIZE);

}


in my system produces:


john@john-desktop:~/Projects/Other/anjuta1/src$ ./foobar_cpp

Creating vector with 10 SomeClass objects...
721719660 2021996343 352419231 1918327853 2096709369 504143813
1554377841 1136725920 697167326 165934869

john@john-desktop:~/Projects/Other/anjuta1/src$


(10 values) instead of 100 values. Is it a compiler defect, or am I
missing something?

== 3 of 3 ==
Date: Thurs, Oct 2 2008 10:12 am
From: Jeff Schwab


Ioannis Vranos wrote:
> The code:
>
> #include <iostream>
> #include <ctime>
> #include <vector>
> #include <cstddef>
>
>
> struct SomeClass
> {
> typedef std::vector<int> TypeVector;
>
> TypeVector vec;
>
> enum { VectorSize= 10 };
>
> public:
>
> SomeClass();
> };
>
>
>
> SomeClass::SomeClass():vec(VectorSize)
> {
> using namespace std;
>
> srand(0);
>
> for(TypeVector::size_type i= 0; i< vec.size(); ++i)
> {
> vec[i]= rand();
>
> cout<<vec[i]<<"\t";
> }
>
> cout<<"\n\n";
> }
>
>
>
> int main()
> {
> using namespace std;
>
> const size_t SIZE=10;
>
> typedef vector<SomeClass> Vector;
>
> cout<< "\nCreating vector with "<< SIZE<< " SomeClass objects..."<<
> endl;
> Vector vec(SIZE);
>
> }
>
>
>
> in my system produces:
>
> john@john-desktop:~/Projects/Other/anjuta1/src$ ./foobar_cpp
>
> Creating vector with 10 SomeClass objects...
> 1804289383 846930886 1681692777 1714636915
> 1957747793 424238335 719885386 1649760492
> 596516649 1189641421
>
> john@john-desktop:~/Projects/Other/anjuta1/src$
>
>
> (10 values) instead of 100 values. Is it a compiler defect, or am I
> missing something?

Only one instance of SomeClass is default-constructed. Most of the
vector elements are copy-constructed.


==============================================================================
TOPIC: Strange behaviour (corrected)
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/05444e0f6a776b9e?hl=en
==============================================================================

== 1 of 4 ==
Date: Thurs, Oct 2 2008 10:08 am
From: Ioannis Vranos


The code:


#include <iostream>
#include <ctime>
#include <vector>
#include <cstddef>


struct SomeClass
{
typedef std::vector<int> TypeVector;

TypeVector vec;

enum { VectorSize= 10 };

public:

SomeClass();
};

SomeClass::SomeClass():vec(VectorSize)
{
using namespace std;


for(TypeVector::size_type i= 0; i< vec.size(); ++i)
{
vec[i]= rand();

cout<<vec[i]<<" ";
}

cout<<"\n\n";
}

int main()
{
using namespace std;

srand(time(0));

const size_t SIZE=10;

typedef vector<SomeClass> Vector;

cout<< "\nCreating vector with "<< SIZE<< " SomeClass objects..."<<
endl;
Vector vec(SIZE);

}


in my system produces:


john@john-desktop:~/Projects/Other/anjuta1/src$ ./foobar_cpp

Creating vector with 10 SomeClass objects...
73703028 1208935909 602693459 1501639085 1773871829 541492682
713359358 1018154590 823363404 280191048

john@john-desktop:~/Projects/Other/anjuta1/src$


(10 values) instead of 100 values. Is it a compiler defect, or am I
missing something?

== 2 of 4 ==
Date: Thurs, Oct 2 2008 10:32 am
From: Victor Bazarov


Ioannis Vranos wrote:
> [...]
> Vector vec(SIZE);
>

Your class is missing the copy constructor.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask

== 3 of 4 ==
Date: Thurs, Oct 2 2008 10:54 am
From: Ioannis Vranos


Victor Bazarov wrote:
> Ioannis Vranos wrote:
>> [...]
>> Vector vec(SIZE);
>>
>
> Your class is missing the copy constructor.


Shouldn't I get a diagnostic?

== 4 of 4 ==
Date: Thurs, Oct 2 2008 10:56 am
From: Ioannis Vranos


Victor Bazarov wrote:
> Ioannis Vranos wrote:
>> [...]
>> Vector vec(SIZE);
>>
>
> Your class is missing the copy constructor.

The code:


#include <iostream>
#include <ctime>
#include <vector>
#include <cstddef>


struct SomeClass
{
typedef std::vector<int> TypeVector;

TypeVector vec;

enum { VectorSize= 10 };

public:

SomeClass();
SomeClass(const SomeClass &);
};

SomeClass::SomeClass():vec(VectorSize)
{
using namespace std;


for(TypeVector::size_type i= 0; i< vec.size(); ++i)
{
vec[i]= rand();

cout<<vec[i]<<" ";
}

cout<<"\n\n";
}


SomeClass::SomeClass(const SomeClass &arg):vec(arg.vec) {}

int main()
{
using namespace std;

srand(time(0));

const size_t SIZE=10;

typedef vector<SomeClass> Vector;

cout<< "\nCreating vector with "<< SIZE<< " SomeClass objects..."<<
endl;
Vector vec(SIZE);

}


still produces:

john@john-desktop:~/Projects/Other/anjuta1/src$ ./foobar_cpp

Creating vector with 10 SomeClass objects...
1843119438 547869594 571665984 1629263681 1309619246 1217447082
488471487 1269191257 74219401 991479353

john@john-desktop:~/Projects/Other/anjuta1/src$


(10 values instead of 100).

==============================================================================

You received this message because you are subscribed to the Google Groups "comp.lang.c++"
group.

To post to this group, visit http://groups.google.com/group/comp.lang.c++?hl=en

To unsubscribe from this group, send email to comp.lang.c+++unsubscribe@googlegroups.com

To change the way you get mail from this group, visit:
http://groups.google.com/group/comp.lang.c++/subscribe?hl=en

To report abuse, send email explaining the problem to abuse@googlegroups.com

==============================================================================
Google Groups: http://groups.google.com/?hl=en

No comments: