Thursday, October 2, 2008

26 new messages in 8 topics - digest

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

comp.lang.c++@googlegroups.com

Today's topics:

* 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
* templates - 3 messages, 1 author
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/72aa4d4f4ae0f080?hl=en
* Map losing elements!? - 4 messages, 2 authors
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/609ccdff4903d004?hl=en
* throwing dtors... - 6 messages, 4 authors
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/ec97ab562016d016?hl=en
* extern const variable in case label - 3 messages, 2 authors
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/d0ae89b0e42f5a54?hl=en
* cout vs std::cout - 2 messages, 2 authors
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/4f48acdaa9e16cee?hl=en
* File Processing - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/74e09fb9aa4d8a51?hl=en
* STL container question - 3 messages, 1 author
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/d2af39d060636197?hl=en

==============================================================================
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 12:37 am
From: James Kanze


On Oct 1, 11:59 am, Ioannis Vranos <ivra...@no.spam.nospamfreemail.gr>
wrote:
> Hi, I am currently learning QT, a portable C++ framework which
> comes with both a commercial and GPL license, and which
> provides conversion operations to its various types to/from
> standard C++ types.

> For example its QString type provides a toWString() that
> returns a std::wstring with its Unicode contents.

In what encoding format? And what if the "usual" encoding for
wstring isn't Unicode (the case on many Unix platforms).

> So, since wstring supports the largest character set, why do
> we need explicit Unicode types in C++?

Because wstring doesn't guarantee Unicode, and implementers
can't change what it does guarantee in their particular
implementation.

> I think what is needed is a "unicode" locale or at the most,
> some unicode locales.

Well, to begin with, there are only two sizes of character
types; the various Unicode encoding forms come in three sizes,
so you already have a size mismatch. And since wchar_t already
has a meaning, we can't just arbitrarily change it.

> I don't consider being compatible with C99 as an excuse.

How about being compatible with C++03?

--
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

== 2 of 4 ==
Date: Thurs, Oct 2 2008 12:41 am
From: James Kanze


On Oct 1, 6:28 pm, REH <spamj...@stny.rr.com> wrote:

[...]
> wstring in the standard defines neither the character set, nor the
> encoding. Given that Unicode is currently a 21-bit standard, how can
> wstring support the largest character set on a system where wchar_t is
> 16-bits (assuming a one-character-per-element encoding)? You could
> only support the BMP (which is exactly what most systems and language
> that "claim" Unicode support are really capable of).

No. Most systems that claim Unicode support on 16 bits use
UTF-16. Granted, it's a multi-element encoding, but if you're
doing anything serious, effectively, so is UTF-32. (In
practice, I find that UTF-8 works fine for a lot of things.)

--
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

== 3 of 4 ==
Date: Thurs, Oct 2 2008 3:21 am
From: Hendrik Schober


James Kanze wrote:
> On Oct 1, 11:59 am, Ioannis Vranos <ivra...@no.spam.nospamfreemail.gr>
> wrote:
>> Hi, I am currently learning QT, a portable C++ framework which
>> comes with both a commercial and GPL license, and which
>> provides conversion operations to its various types to/from
>> standard C++ types.
>
>> For example its QString type provides a toWString() that
>> returns a std::wstring with its Unicode contents.
>
> In what encoding format? And what if the "usual" encoding for
> wstring isn't Unicode (the case on many Unix platforms).

<curious>
What are those implementations using for 'wchar_t'?
</curious>

Schobi

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


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?

> and since
> we will get Unicode types it is a good idea to use wchar_t for encodings
> not the same size as the Unicode types.


I am talking about not needing those Unicode types since we have wchar_t
and locales.


==============================================================================
TOPIC: templates
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/72aa4d4f4ae0f080?hl=en
==============================================================================

== 1 of 3 ==
Date: Thurs, Oct 2 2008 12:51 am
From: James Kanze


On Oct 1, 10:46 pm, Pete Becker <p...@versatilecoding.com> wrote:
> On 2008-10-01 16:20:02 -0400, Jeff Schwab <j...@schwabcenter.com> said:
> > James Kanze wrote:
> >> On Oct 1, 2:58 pm, Jeff Schwab <j...@schwabcenter.com> wrote:
> >>> puzzlecracker wrote:

> >>> The export feature never caught on because it requires much
> >>> more powerful linkers than people actually have, or else some
> >>> heavy-handed work-arounds in the build environment.

> >> Comeau seems to do it without any problems. With the system
> >> standard linker.

> > How does Comeau know, as it parses the template definition, which
> > instantiations will be necessary in a particular application? This
> > information cannot be known until link time, which is the first time
> > the whole application is seen by the same tool. At that point, during
> > the link, the compiler must be re-invoked, to compile whichever
> > template instantiations are needed by the various object files. Of
> > course, standard linkers do not re-invoke the compiler with lists of
> > template instantiations, so "export" does not work with them. Either
> > all tranlation units (that rely on exported template definitions) have
> > to be available at the same time, or else a special linker
> > must be used.

> Not necessarily. I haven't looked at how Comeau does it, but
> one approach would be for a driver program to parse the error
> messages from the linker to figure out which template
> instantiations to generate next.

You mean like CFront did:-).

The real problem isn't knowing which templates to instantiate.
There are tons of solutions for that. The real problem is
synthesizing the correct instantiation context once you've
decided to generate them. There is a sense in which Jeff is
right: the information in a typical object file (.o or .obj)
isn't sufficient, and that's all typical linkers deal with. But
there's no rule that a compiler can only generate object files;
if I look in a directory where I've compiled with VC++, I find
not only my sources, the .obj and the .exe, but also .ilk and
.pdb, and there's nothing to prevent compilers from doing
likewise under Unix. And there's nothing to prevent the
compiler from using some other mechanism---didn't Visual Age use
a data base for such things?

It's clear that you need more than the classical compile and
link. But that's why you invoke g++ instead of gcc (or CC
instead of cc---VC++ uses a different technique to decide what
to do, but you still invoke cl to link, and not link); the
driver invokes whatever additional steps are necessary.

--
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

== 2 of 3 ==
Date: Thurs, Oct 2 2008 12:55 am
From: James Kanze


On Oct 1, 11:50 pm, Hendrik Schober <spamt...@gmx.de> wrote:
> Jeff Schwab wrote:
> > James Kanze wrote:
> >> On Oct 1, 2:58 pm, Jeff Schwab <j...@schwabcenter.com> wrote:
> >>> puzzlecracker wrote:
> >>> The export feature never caught on because it requires much
> >>> more powerful linkers than people actually have, or else some
> >>> heavy-handed work-arounds in the build environment.
> >> Comeau seems to do it without any problems. With the system
> >> standard linker.

> > How does Comeau know, as it parses the template definition,
> > which instantiations will be necessary in a particular
> > application? [...]

> I wouldn't know, but from what I understand, it seems that
> you cannot implement 'export' while sticking to the old
> one-translation-unit-at-a-time approach anyway.

In a certain sense, you can't implement templates with this
approach. The old one-translation-unit-at-a-time approach
doesn't allow for duplicate definitions.

I don't think it's the case with Comeau, but an implementation
could certainly require the sources for the templates to have
been compiled before compiling client code, or even require the
sources to be available when compiling client code. You'd loose
some of the advantages of export, but you'd still get one
important advantage: definitions in the client code (including
macros!) would not be used when compiling the template
instantiation, except for dependent names.

--
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

== 3 of 3 ==
Date: Thurs, Oct 2 2008 12:57 am
From: James Kanze


On Oct 1, 10:35 pm, Paavo Helde <nob...@ebi.ee> wrote:
> puzzlecracker <ironsel2...@gmail.com> kirjutas:

> As far as I have understood, one of the most important points
> the standards committee considers for each new feature is its
> implementability. If they would not do that, the standard
> would lose its credibility.

> I believe they failed with the template export in this regard,
> and that's why it is generally not implemented. Fortunately,
> this does not affect much the usability of templates
> themselves.

Except for making templates unusable at the application level.
(And of course, export is implementable, since it has been
implemented. By a company with a lot less resources than
Microsoft or Sun.)

--
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


==============================================================================
TOPIC: Map losing elements!?
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/609ccdff4903d004?hl=en
==============================================================================

== 1 of 4 ==
Date: Thurs, Oct 2 2008 1:09 am
From: James Kanze


On Oct 2, 2:44 am, Johannes Bauer <dfnsonfsdu...@gmx.de> wrote:

> I've been trying around with a simple std::map<mytype,
> unsigned> for an hour now and can't find the bug. It is my
> belief that I am missing something incredibly obvious...
> please help me see it.

> Scenario: I created the map and inserted some elements.
> Afterwards I try to iterate over them:

> std::map<mytype, unsigned int> values;
> /* insert some values, say 5 */

> /* this will then report 5 */
> std::cerr << "cnt = " << values.size() << std::endl;

> for (std::map<mytype, unsigned int>::iterator j = values.begin(); j !=
> values.end(); j++) {
> std::cerr << j->second << " -> ";
> j->first.Dump();
> std::cerr << std::endl;
> }

> However in the "for" loop, always only 2 items show up. I
> figured something was wrong with my operator< - essentialy
> "mytype" is just a container around a LENGTH byte unsigned
> char[] array:

> bool operator<(const mytype &Other) const {
> for (unsigned int i = 0; i < LENGTH; i++) {
> if (Other.Data[i] < Data[i]) return true;
> }
> return false;
> }

> Can anyone explain this behaviour?

Your comparison operator is obviously wrong. If we suppose Data
is an int[3], then what happens if you compare { 1, 2, 3 } and
{ 2, 1, 3 }. Regardless of the order, you're function returns
true, i.e. given
Data a = { 1, 2, 3 } ;
Data b = { 2, 1, 3 } ;
your function returns true for both a<b and b<a. One of the
requirements is that if a<b, then !(b<a). What you probably
want is something more like:

for ( int i = 0 ;
i != LENGTH && data[ i ] == other.data[ i ] ;
++ i ) {
}
return i != LENGTH
&& data[ i ] < other.data[ i ] ;

(In this case, your result depends entirely on the first
non-equal element, and if false if all elements are equal.)

--
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

== 2 of 4 ==
Date: Thurs, Oct 2 2008 1:16 am
From: James Kanze


On Oct 2, 3:22 am, Sam <s...@email-scan.com> wrote:
> Johannes Bauer writes:
> > I've been trying around with a simple std::map<mytype,
> > unsigned> for an hour now and can't find the bug. It is my
> > belief that I am missing something incredibly obvious...
> > please help me see it.

> > Scenario: I created the map and inserted some elements.
> > Afterwards I try to iterate over them:

> > std::map<mytype, unsigned int> values;
> > /* insert some values, say 5 */

> > /* this will then report 5 */
> > std::cerr << "cnt = " << values.size() << std::endl;

> > for (std::map<mytype, unsigned int>::iterator j = values.begin(); j !=
> > values.end(); j++) {
> > std::cerr << j->second << " -> ";
> > j->first.Dump();
> > std::cerr << std::endl;
> > }

> > However in the "for" loop, always only 2 items show up. I
> > figured something was wrong with my operator< - essentialy
> > "mytype" is just a container around a LENGTH byte unsigned
> > char[] array:

> > bool operator<(const mytype &Other) const {
> > for (unsigned int i = 0; i < LENGTH; i++) {
> > if (Other.Data[i] < Data[i]) return true;
> > }
> > return false;
> > }

> > Can anyone explain this behaviour?

> Although your operator< does look wrong, this wouldn't really
> explain your claimed problem. If there are 5 elements in the
> map, then there are 5 elements in the plan.

It's undefined behavior. Consider an implementation which
maintains a dummy node for end, and a separate count for all
insertions. An error in the comparison operator could easily
cause the implementation to insert the node behind end, or
somewhere else it is no longer accessible. More generally, once
he has inserted an element using this comparison function,
anything goes.

--
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

== 3 of 4 ==
Date: Thurs, Oct 2 2008 2:01 am
From: Guy.Tristram@gmail.com


On 2 Oct, 01:44, Johannes Bauer <dfnsonfsdu...@gmx.de> wrote:
> bool operator<(const mytype &Other) const {
>         for (unsigned int i = 0; i < LENGTH; i++) {
>                 if (Other.Data[i] < Data[i]) return true;
>         }
>         return false;
>
> }

You could use std::lexicographical_compare:

bool operator<(const mytype &Other) const {

== 4 of 4 ==
Date: Thurs, Oct 2 2008 2:04 am
From: Guy.Tristram@gmail.com


On 2 Oct, 10:01, Guy.Trist...@gmail.com wrote:
> On 2 Oct, 01:44, Johannes Bauer <dfnsonfsdu...@gmx.de> wrote:
>
> > bool operator<(const mytype &Other) const {
> >         for (unsigned int i = 0; i < LENGTH; i++) {
> >                 if (Other.Data[i] < Data[i]) return true;
> >         }
> >         return false;
>
> > }
>
> You could use std::lexicographical_compare:
>
> bool operator<(const mytype &Other) const {

oops...

bool operator<(const mytype &Other) const {
return std::lexicographical_compare( Other.Data, Other.Data +
LENGTH, Data, Data + LENGTH );
}

should do the trick.

Guy


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

== 1 of 6 ==
Date: Thurs, Oct 2 2008 1:21 am
From: anon


Chris M. Thomasson wrote:
> "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...
>>
>> Take a look here:
>> http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.13
> [...]
>
> Well, AFAICT, it seems like C++ destructors are really not all that good
> for gracefully handling critical shutdown operations in dtors, such as
> `fclose()'. Where am I going wrong? It seems like the only way to avoid
> throwing from a dtor would be doing something along the lines of:
>

Destructors have to cleanup its objects, and they should (must) not fail.

>
> // example on how to handle EINTR or perhaps even EAGAIN
> ______________________________________________________________________
> class file {
> FILE* m_handle;
>
> // returns true to retry; or false to continue...
> bool (*m_fp_on_fclose_dtor) (int);
>
> public:
> file(bool (*fp_on_fclose_dtor) (int) = NULL, ...)
> : m_fp_on_fclose_dtor(fp_on_fclose_dtor) {
> // [...];
> }
>
> ~file() throw() {
> while (fclose(m_handle) == EOF) {
> if (m_fp_on_fclose_dtor && !
> m_fp_on_fclose_dtor(errno)) {
> break;
> }
> }
> }
> };
>
>

IMO This would be better:

class file {
FILE* m_handle;

public:
file()
{
// [...];
}

~file()
{
try
{
close_file();
}
// catch other exceptions
catch(...)
{
// log the error
}
}

void close_file()
{
// do whatever you can to close the file
// throw an exception in a case of an error
}

};

int main()
{
try
{
file obj;
// do stuff
obj.close_file();
}
catch(...)
{
// log error
// try to repair the damage
}
}

>
> Now, if a signal is thrown, or if the operation would block, the
> operation will at least try to gracefully complete. All other errors
> KILL the program dead... Sounds good to me.
>
>

With all other errors, your file will not be closed, and you have a
terminated program. Not very elegant solution ;)

== 2 of 6 ==
Date: Thurs, Oct 2 2008 1:27 am
From: James Kanze


On Oct 2, 5:25 am, "Chris M. Thomasson" <n...@spam.invalid> wrote:
> Is it every appropriate to throw in a dtor?

Sure. There are special cases where the only reason to have a
destructor is for it to throw.

All such cases are, however, special cases, and objects of those
types should only exist in special contexts (typically, as
temporaries in a single expression).

> I am thinking about a simple example of a wrapper around a
> POSIX file...

That one definitly shouldn't throw.

> ________________________________________________________________________
> class file {
> FILE* m_handle;

> public:
> // [...];

> ~file() /* throw() */ {
> int const status fclose(m_handle);
> if (status) {
> /* shi% hit the fan:
> http://www.opengroup.org/onlinepubs/007908775/xsh/fclose.html
> /*
> // [what now?]
> }
> }
> };
> ________________________________________________________________________

If you get to the destructor and the file hasn't been closed,
it's an error. It should only happen in two cases: your
unwinding the stack as a result of another error (which will
result in the generated file being deleted, or at least marked
as invalid), or there is an error elsewhere in the code (which
should result in an assertion failure).

> How to properly handle `EAGAIN' in dtor? Well, what about any
> error for that matter? I am a C programmer and only code C++
> for fun, and some in-house projects. If I were really going to
> create C++ application and release it into the wild, well, how
> would you advise me to handle the case above?

Require an explicit close by the user, before the object is
destructed, and return a return code from that function.

FWIW: most of my file output is through a file wrapper class
whose destructor deletes the file if it is called before the
file is "committed"; it also has an option for linking several
such wrappers, so that all of the files will be deleted unless
all have been successfully "committed". (Also, my shutdown
routines flush cout, and generate an error if that fails.)

[...]
> Please keep in mind that refusing to not handle an error from
> `fclose' could resule is HORRIBLE things down the road...

Obviously. And since the error must be handled, you never count
on the destructor for the close. (In the normal case---it's
fine if you're cleaning up after another error, and are going to
delete the file anyway as a result of the other error.)

--
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

== 3 of 6 ==
Date: Thurs, Oct 2 2008 1:31 am
From: James Kanze


On Oct 2, 7:47 am, anon <a...@no.invalid> wrote:

[...]
> What can you do when fclose fails?

At the very least, you must notify the user. Generally, you'll
want to delete the file, and usually return an error code to the
OS.

About the only exception I can think of is a log file. If
closing that fails, you probably want to continue anyway,
ignoring the error. (Theoretically, you should log the
error:-).)

--
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

== 4 of 6 ==
Date: Thurs, Oct 2 2008 1:36 am
From: James Kanze


On Oct 2, 9:20 am, "Chris M. Thomasson" <n...@spam.invalid> wrote:
> "Paavo Helde" <nob...@ebi.ee> wrote in message

[...]
> > For most applications I believe a proper behavior would be
> > to try to log the error somewhere, then either continue or
> > abort, depending on the application type.

> What if the application needs to copy a file to disk and
> destroy the original? If `fclose()' fails on the destination
> file, well, the application won't know about it and will
> continue on and destroy the source file. Well, the
> destination file is by definition in a non-coherent state
> because `fclose()' failed to "do its thing". Well, the lost
> data is gone forever. A log file will only show why the data
> was lost, it does not prevent it. In this case I bet the user
> wished the application just terminated when the `fclose()'
> failed. Or better, I bet the user would like to be able to
> catch and explicitly handle this case...

This is why it is important in such cases to return an error
status (EXIT_FAILURE) from main. A typical idiom in Unix would
be something like:

program filename > tempFile && mv tempFile filename

And all too often, the program won't flush standard out and
verify that the flush worked. (All to many programs totally
ignore the fact that output might fail.) With the result that
if you fill up the disk, you loose important data.

--
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

== 5 of 6 ==
Date: Thurs, Oct 2 2008 1:39 am
From: Paavo Helde


"Chris M. Thomasson" <no@spam.invalid> kirjutas:

>
> "Paavo Helde" <nobody@ebi.ee> wrote in message
> news:Xns9B2B65D8AFDA9nobodyebiee@216.196.97.131...
>> "Chris M. Thomasson" <no@spam.invalid> kirjutas:
>>
>>> Is it every appropriate to throw in a dtor? I am thinking about a
>>> simple example of a wrapper around a POSIX file...
>>> _____________________________________________________________________
>>> __
> [...]
>>
>> Throwing from a dtor is not really advisable in C++. It can easily
>> lead to duplicate throws during stack unwinding, and calling
>> terminate() as the result.
>>
>> The C++ RAII model is built up on the assumption that releasing the
>> resource always succeeds (or its failure can be ignored by upper
>> levels). If this is not the case, then the application logic becomes
>> very complex immediately, essentially you are back in C again.
>>
>> In any case, I would suggest to move any activity which can fail out
>> of the destructor, into a separate member function which has to be
>> called explicitly before destroying of the object, possibly from
>> inside a try- catch block dealing with errors.
>
> I think I agree here. Since, IMVHO, at least attempting to gracefully
> handle `fclose()', such as deferred retrying in the case of `EINTR' or
> `EAGAIN', is extremely important. Therefore, it sure seems to make
> sense to force the used to explicitly call a member function which
> invokes `fclose()' and throws when a very bad error its encountered
> (e.g., something other than EINTR or EAGAIN).
>

Exceptions are for communicating situations which cannot be dealt locally
to the upper levels in the application logic. If the error can be dealt
locally, there is no need for an exception.

I am not familiar with EAGAIN, but can't this be handled locally as well?


[...]
> What if the application needs to copy a file to disk and destroy the
> original? If `fclose()' fails on the destination file, well, the
> application won't know about it and will continue on and destroy the

Apparently, it has to know about this in this case. So fclose() result
has to be somehow communicated to the calling application. Unfortunately
it cannot be done just by throwing an exception from the destructor.
Well, in principle there is the uncaught_exception() function which one
could check in the dtor and decide whether to throw a new exception or if
there is one already in the progress, and so no new exception is needed.
However, there were some gotchas which made uncaught_exception() mostly
useless IIRC.

Paavo

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


In article <X5_Ek.12946$ex3.3200@newsfe02.iad>,
Chris M. Thomasson <no@spam.invalid> wrote:
>"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...
>>
>> Take a look here:
>> http://www.parashift.com/c++-faq-lite/dtors.html#faq-11.13
>
>Okay; I will give it a look.
>
>[...]
>
>> How would you handle it in C?
>[...]
>
>> What can you do when fclose fails?
>
>Well, it depends on the error:
>
>http://www.opengroup.org/onlinepubs/007908775/xsh/fclose.html
>
>For instance, fclose can get interrupted by a signal. In this case, you need
>to reissue the operation; e.g:
>______________________________________________________________
>struct file {
> FILE* handle;
>};
>
>int file_close(
> struct file* const this
>) {
> int status;
> do {
> status = fclose(this->handle);
> } while (status == EOF && errno == EINTR);
> return status;
>}

That's precisely your answer:

Do exactly what you would do in C in your file_close method
and call it from your destructor:

File::~File()
{
if(0 != file_close()) {
// log the error
// or std::terminate?
}
}

int File::file_close()
{
int status = 0;
do {
status = fclose(handle);
} while (status == EOF && errno == EINTR);
return status;
}


>Or, what if it returns `EAGAIN', well, this certainly needs to be handled.

So handle EAGAIN. 2 ways:

1- in file_close()
2- if impossible in file_close() then you must require that the client do
it by explicitely calling file_close() and dealing with errors.


>Fine... Now, a user needs to copy a file to a disk, and destroy the
>original. Okay. It creates two file objects (e.g., src and dest:)
>
>{
> file src(...);
> file dest(...);
>
> // Then it performs the copy operation:
>
> [copy src to dest]
>}
>
>
>
>Now the code-block goes out of scope, and no exceptions were thrown during
>the copy process, HOWEVER, the call to `fclose()' in the dest object
>failed!!!! Well, the user thinks everything is fine because the completely
>retarded ignorant moron file object did not report the fuc%ing error! So the
>user operates in ignorance and happily destroys the original file thinking
>that the file was COMPLETELY copied onto the disk! WRONG! The file was
>partially copied because `fclose()' failed to do its thing and properly
>flush the buffers, or whatever... Now, the missing file data is LOST
>__forever__! OUCH!!!

That's a failure of the application

foo()
{
file src(...)
file dest(...)
dest.copy(src);

// Must ensure that dest was correctly flushed/sync/close *before*
// deleting src
if(0 == dest.file_close())
{
src.delete();
} else {
// whatever is needed to recover
}
}



==============================================================================
TOPIC: extern const variable in case label
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/d0ae89b0e42f5a54?hl=en
==============================================================================

== 1 of 3 ==
Date: Thurs, Oct 2 2008 2:23 am
From: "Christian Meier"


Hello NG

I have the following code:


file1.h:

static const int iValue = 5;

<EOF>


file2.cpp

#include <iostream>
#include "file1.h"

int main(int args, char* argv[])
{
switch(args) {
case iValue:
std::cout << "Hello\n";
}
}

<EOF>

This works fine as the value of the constant "iValue" is known when
compiling the main()-function in file2.cpp.
I have some more cpp-files which include file1.h. Therefore I have a copy of
"iValue" in each translation unit as it has internal linkage. In the
executable which is made with these object files (translation units) I have
several copies of that variable; all having the same value.

Now, I would like to change the linkage of "iValue" to extern so that there
is only one symbol for this constant in my executable.
When I change the keyword "static" to "extern" I have the problem that the
symbol is more than once defined in my executable.
When I only declare the variable "iValue" in file1.h with external linkage
("extern const int iValue;") and define it in a new file called file1.cpp
("extern const iValue = 5;"), then I have no problem with multiple
definitions but I have a new problem in my function main() because the value
of "iValue" is not known when compiling file2.cpp.

Do you have any suggestions how I can compile all my code without having
more than one symbol for "iValue" in my program? Or is it not possible what
I am trying to reach?


Thanks for all your answers in advance,
Chris


== 2 of 3 ==
Date: Thurs, Oct 2 2008 2:50 am
From: thomas


On Oct 2, 5:23 pm, "Christian Meier" <chris@no_spam.com> wrote:
> Hello NG
>
> I have the following code:
>
> file1.h:
>
> static const int iValue = 5;
>
> <EOF>
>
> file2.cpp
>
> #include <iostream>
> #include "file1.h"
>
> int main(int args, char* argv[])
> {
>     switch(args) {
>     case iValue:
>         std::cout << "Hello\n";
>     }
>
> }
>
> <EOF>
>
> This works fine as the value of the constant "iValue" is known when
> compiling the main()-function in file2.cpp.
> I have some more cpp-files which include file1.h. Therefore I have a copy of
> "iValue" in each translation unit as it has internal linkage. In the
> executable which is made with these object files (translation units) I have
> several copies of that variable; all having the same value.
>
> Now, I would like to change the linkage of "iValue" to extern so that there
> is only one symbol for this constant in my executable.
> When I change the keyword "static" to "extern" I have the problem that the
> symbol is more than once defined in my executable.
> When I only declare the variable "iValue" in file1.h with external linkage
> ("extern const int iValue;") and define it in a new file called file1.cpp
> ("extern const iValue = 5;"), then I have no problem with multiple
> definitions but I have a new problem in my function main() because the value
> of "iValue" is not known when compiling file2.cpp.
>
> Do you have any suggestions how I can compile all my code without having
> more than one symbol for "iValue" in my program? Or is it not possible what
> I am trying to reach?
>
> Thanks for all your answers in advance,
> Chris

well. I think you should keep in mind that the case value can only be
constant integral values.

== 3 of 3 ==
Date: Thurs, Oct 2 2008 3:05 am
From: "Christian Meier"


> well. I think you should keep in mind that the case value can only be
> constant integral values.

What do you exactly mean with this? Isn't "extern const int iValue" a
constant integral value?



==============================================================================
TOPIC: cout vs std::cout
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/4f48acdaa9e16cee?hl=en
==============================================================================

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


In article <gc0i06$qc8$1@cb.generation-online.de>,
Hendrik Schober <spamtrap@gmx.de> wrote:
>Yannick Tremblay wrote:
>> In article <gbqvc0$2um$2@cb.generation-online.de>,
>> Hendrik Schober <spamtrap@gmx.de> wrote:
>>> Yannick Tremblay wrote:
>>>> In article <gbqqk9$v30$1@cb.generation-online.de>,
>>>> Hendrik Schober <spamtrap@gmx.de> wrote:
>>>>> Yannick Tremblay wrote:
>>>>>> [Ridiculous example deleted]
>>>>> No. The next project introduced its string utilities
>>>>> in a namespace 'Strings'.
>>>> But the point remains that "Strings" is less clear than "StringUtility".
>>>>
>>>> In this particular case, the loss of clarity is probably acceptable
>>>> but that virtual ban on namespaces is IMO a bad thing because I
>>>> think it encourages bad naming.
>>> Which ban?
>>
>> I did write *virtual* ban but sorry, I mean virtual ban of "using
>> namespace" not on "namespace" themselves.
>>
>> The exact quote was:
>> "Most of the time I worked under the rule that using declarations (and
>> even using directives!) where allowed within any local scopes not
>> bigger than a function,"
>>
>> IMO, this amount to a virtual ban. [...]
>
> <shrug>
> It's what usually all developers agreed on in those projects.
> It only encourages bad naming when you're afraid of typing
> (or whatever it is that makes people obsessed with writing the
> fewest possible characters.)

But you said it yourself:
"What I've learned, though, is to avoid creating namespaces which are
long and hard to type right even after weeks ('StringUtility') of
usage. :)"

So it did encourage you to use shorter and less informative
identifiers than you initially found appropriate and that you
would have continued using was it not for this IMO dodgy coding
style edict. "String" is a less informative name than
"StringUtility". Why was "StringUtility" origianlly chosen?
Probably because it describes correctly the namespace. Why did you
shorten it to "String"? Because you were bored of typing. Not
because it describes the namespace better, made the code more
readable, more maintainable or anything else.

In this case, "String" might be acceptable but this a only the first
step on a slippery road. Be careful or the namespaces created by
worse programmers than yoursel will start ressembling hungarian
warts.

Yannick


== 2 of 2 ==
Date: Thurs, Oct 2 2008 3:32 am
From: Hendrik Schober


Yannick Tremblay wrote:
> In article <gc0i06$qc8$1@cb.generation-online.de>,
> Hendrik Schober <spamtrap@gmx.de> wrote:
>> Yannick Tremblay wrote:
>>> In article <gbqvc0$2um$2@cb.generation-online.de>,
>>> Hendrik Schober <spamtrap@gmx.de> wrote:
>>>> Yannick Tremblay wrote:
> [...]
>>> IMO, this amount to a virtual ban. [...]
>> <shrug>
>> It's what usually all developers agreed on in those projects.
>> It only encourages bad naming when you're afraid of typing
>> (or whatever it is that makes people obsessed with writing the
>> fewest possible characters.)
>
> But you said it yourself:
> "What I've learned, though, is to avoid creating namespaces which are
> long and hard to type right even after weeks ('StringUtility') of
> usage. :)"
>
> So it did encourage you to use shorter and less informative
> identifiers [...]

No. It encouraged to use names that are easier to type.
That doesn't mean they had to be shorter or even less
informative. (But that was when we used an editor that
had no useful typing support. Nowadays probably nobody
would care.)
(Oh, and it was "Strings", not "String". :^> )

> In this case, "String" might be acceptable but this a only the first
> step on a slippery road. Be careful or the namespaces created by
> worse programmers than yoursel will start ressembling hungarian
> warts.

Don't you think that a bunch of programmers who decide
that they generally want to explicitly spell out every
namespace name for every identifier have a typing pain
threshold high enough to not to shorten names beyond
usability?

> Yannick

Schobi


==============================================================================
TOPIC: File Processing
http://groups.google.com/group/comp.lang.c++/browse_thread/thread/74e09fb9aa4d8a51?hl=en
==============================================================================

== 1 of 1 ==
Date: Thurs, Oct 2 2008 2:54 am
From: "Jeff"


Thanks a million for the very helpful replies.

I'm still experimenting, but I already found that I can make significant
(>10) improvements in speed by buffering in the file rather than reading it
byte by byte.

Jeff



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

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


Juha Nieminen wrote:
> Ioannis Vranos wrote:
>> Lists are implemented using pointers to point to the previous and to the
>> next elements, so list::sort(), is more efficient by changing pointer
>> values, while sorting a vector involves copying objects.
>
> The original poster talked about storing integer values. I highly
> doubt sorting a list of integers will be faster than sorting an array of
> integers. In fact, I'm pretty sure of the contrary.


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.


If the programmer decides to replace ints with other objects, he will
not have to change much in the code, if he uses a list.

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


Pete Becker wrote:
>
> In other words, no. <g> One could also point out that quicksort can be
> used to sort a vector but can't be used on a list, so obviously sorting
> a vector is faster.


list::sort is faster than any sort on vector, because it does not
involve the construction or destruction of any object.

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


James Kanze wrote:
> To other considerations: you can't use binary_search on
> std::list---with any sort of size, that's going to make a
> significant difference in favor of vector.


Of course you can:


#include <algorithm>
#include <list>
#include <cstddef>
#include <iostream>


int main()
{
using namespace std;

typedef list<int> intlist;

intlist ilist;


for (size_t i= 0; i< 100; ++i)
ilist.push_back(100-i);


ilist.sort();


for(intlist::const_iterator p= ilist.begin(); p!= ilist.end(); ++p)
cout<< *p<< endl;


binary_search(ilist.begin(), ilist.end(), 50);
}

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

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: