Saturday, March 28, 2009

comp.lang.c++ - 25 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:

* Nomenclature for interger size in C/C++ - 5 messages, 4 authors
http://groups.google.com/group/comp.lang.c++/t/d94de8ebc4095151?hl=en
* Processing a text file - 3 messages, 3 authors
http://groups.google.com/group/comp.lang.c++/t/56af946467295a55?hl=en
* Unignorable return value - 4 messages, 3 authors
http://groups.google.com/group/comp.lang.c++/t/3b14b8ccfba9854c?hl=en
* Standard C++ way to generate a Jump Table ??? - 3 messages, 2 authors
http://groups.google.com/group/comp.lang.c++/t/7686e7082cfac191?hl=en
* Question about reading from stream. - 2 messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/52af4ea746edf596?hl=en
* Is this a good reference-counting smart pointer class? - 4 messages, 3
authors
http://groups.google.com/group/comp.lang.c++/t/41558400ad1ce160?hl=en
* how to convert a binary file to base64? - 2 messages, 2 authors
http://groups.google.com/group/comp.lang.c++/t/7aa8fbb30055a8db?hl=en
* Design question: polymorphism after object creation - 2 messages, 2 authors
http://groups.google.com/group/comp.lang.c++/t/b748f0f3d941a3ba?hl=en

==============================================================================
TOPIC: Nomenclature for interger size in C/C++
http://groups.google.com/group/comp.lang.c++/t/d94de8ebc4095151?hl=en
==============================================================================

== 1 of 5 ==
Date: Sat, Mar 28 2009 7:29 am
From: Victor Bazarov


Arne Mertz wrote:
> Ian Collins schrieb:
>> Giuliano Bertoletti wrote:
>>>
>>> Hello,
>>>
>>> I was just wondering if there's a standard nomenclature which forces
>>> any C/C++ compiler to instantiate integer variables of a givens size.
>>
>> Use the widely supported C99 fixed width types (int64_t and friends)
>> from stdint.h.
>>
> Or use boost::integers that is designed to do the same job "whithout
> resorting to undefined behaviour in terms of the 1998 C++ Standard."
>
> http://www.boost.org/doc/libs/1_38_0/libs/integer/index.html

Boost still suports VC6? Wow... Those guys *are* generous.

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


== 2 of 5 ==
Date: Sat, Mar 28 2009 8:14 am
From: Arne Mertz


Victor Bazarov schrieb:
> Arne Mertz wrote:
>> Ian Collins schrieb:
>>> Giuliano Bertoletti wrote:
>>>>
>>>> Hello,
>>>>
>>>> I was just wondering if there's a standard nomenclature which forces
>>>> any C/C++ compiler to instantiate integer variables of a givens size.
>>>
>>> Use the widely supported C99 fixed width types (int64_t and friends)
>>> from stdint.h.
>>>
>> Or use boost::integers that is designed to do the same job "whithout
>> resorting to undefined behaviour in terms of the 1998 C++ Standard."
>>
>> http://www.boost.org/doc/libs/1_38_0/libs/integer/index.html
>
> Boost still suports VC6? Wow... Those guys *are* generous.
>
> V
Well, I didn't know at that point that the OP is using that
prehistoric artifact. But yes, Boost kind of supports VC6, mainly by
disabling tons of features that rely on the parts of standard C++
VC6 is not capable to compile.
I have not dug deep enough into the boost::integer headers to find
out how much of the features will be turned off for VC6, but luckily
I have no need nor intention to ever use that compiler.

Arne


== 3 of 5 ==
Date: Sat, Mar 28 2009 10:07 am
From: Giuliano Bertoletti


Victor Bazarov ha scritto:

>
> So, instead of learning to drive and operate a new, clean, fast,
> spacious, and otherwise modern vehicle, you'd rather drive the old,
> smoldering, slow, rusty, falling apart, not to mention incapable of
> fulfilling some of your requirements, clunker? Good for you. And the
> users of your program. I am guessing you've not got many, and the ones
> you do have, keep their balls in your capable hands (NTTIAWWT).
>

You're making assumptions and jump to conclusion without enough information.

It's a matter of trade-offs. I've nothing against new compilers but the
question you may ask yourself is: should I invest time in learning how
to use that new compiler and then port my application or should I keep
developing features with what I have ?

In my opinion it weights much more in the decision the need for some
specific library that may not work with the current version used rather
than conformity to standards (I can easily bypass the int64_t issue, it
was just a curiosity).

When I speak of libraries I mean something substantial which is unlikely
you might develop or workaround easily (for example a library for
editing .pdf files which you would treat as a black-box).

>
> If they work fine, they would work just as fine compiled with a more
> modern compiler. Why would you thing they are going to start failing?
> Is that because they are held together with a piece of old twine and a
> prayer?
>

No, it's not a matter of code being brittle. It's that porting a project
costs and may expose you to problems with an otherwise working system.

If your software is mission critical and a failure (or even a delay in
delivery a new version) can cost you money, then you've better think
twice before upgrading. Unless of course you're forced to.

> MFC is still supported by the most modern of Visual C++ incarnations.
> Most of older programs don't require much attention. Yes, you need to
> port (to straighten out the code you had to write to overcome the
> deficiencies of the pre-Standard compiler and its library), yes, you
> need testing.

Porting and testing are not always minor nuissances. They're often major
stumbling blocks. Especially if you're working in a team and you've not
written yourself all the code.

>> However MFC is badly supported by new compilers that are oriented to
>> .NET framework.
>
> Nonsense. You've apparently not been keeping up, so your opinion can't
> really count, can it? Post your questions/concerns to the newsgroup
> 'microsoft.public.vc.language' or 'microsoft.public.vc.mfc' and see what
> reaction you get.
>

Modern MS compilers are implicitly discouraging the use of MFC. The GUIs
are heading toward managed code (C#, VB, etc.) which offer better
development time and features richness in exchange for bloated and
slower applications.
This may or may not be ok, but that's where MS is heading to.
In the VS9 presentation, they refer to the C++ compiler as a great tool
to develop games.

Back to MFC, they lack for example the ClassWizard which is an handy
tool for developing MFC based classes. Sure, you can write the code by
hand, define all the marco yourself and so on. Is it worth ?

Again, the anwser is not obvious.

Regards,
Giuliano Bertoletti.


== 4 of 5 ==
Date: Sat, Mar 28 2009 11:39 am
From: "Thomas J. Gritzan"


Giuliano Bertoletti schrieb:
> Victor Bazarov ha scritto:
>>> However MFC is badly supported by new compilers that are oriented to
>>> .NET framework.
>>
>> Nonsense. You've apparently not been keeping up, so your opinion
>> can't really count, can it? Post your questions/concerns to the
>> newsgroup 'microsoft.public.vc.language' or 'microsoft.public.vc.mfc'
>> and see what reaction you get.
>>
>
> Modern MS compilers are implicitly discouraging the use of MFC. The GUIs
> are heading toward managed code (C#, VB, etc.) which offer better
> development time and features richness in exchange for bloated and
> slower applications.

Microsoft noticed that MFC and native C++ is still widely used and
released an update to MFC a year ago:

"On April 7, 2008, Microsoft released an update to the MFC classes as an
out-of-band update to Visual Studio 2008 and MFC 9."

"The MFC application wizard has also been upgraded to support the new
features"

http://en.wikipedia.org/wiki/Microsoft_Foundation_Class_Library

> This may or may not be ok, but that's where MS is heading to.
> In the VS9 presentation, they refer to the C++ compiler as a great tool
> to develop games.
>
> Back to MFC, they lack for example the ClassWizard which is an handy
> tool for developing MFC based classes. Sure, you can write the code by
> hand, define all the marco yourself and so on. Is it worth ?

Q7: Where is ClassWizard in Visual Studio .NET and in Visual Studio 2005?
Answer:
http://support.microsoft.com/?scid=kb%3Ben-us%3B313981

When you still use VC6 from 10 years ago, you don't profit from the
better optimizations today's compiler can do for you.

--
Thomas


== 5 of 5 ==
Date: Sat, Mar 28 2009 1:30 pm
From: Giuliano Bertoletti


Thomas J. Gritzan ha scritto:

>
> Microsoft noticed that MFC and native C++ is still widely used and
> released an update to MFC a year ago:
>
> "On April 7, 2008, Microsoft released an update to the MFC classes as an
> out-of-band update to Visual Studio 2008 and MFC 9."
>
> "The MFC application wizard has also been upgraded to support the new
> features"
>

I'm not saying that MFC isn't updated or supported.
But, new Visual Studios are heading toward other directions and that's a
fact.

More than the library itself, the tools that support the development are
important. These tools are nowhere experiencing the steady development
and increase in functionality that other tools had.

> Q7: Where is ClassWizard in Visual Studio .NET and in Visual Studio 2005?
> Answer:
> http://support.microsoft.com/?scid=kb%3Ben-us%3B313981
>

It says that ClassWizard is not present and that *some* (but not all) of
the functionalities are carried out by other tools.
What if the missing are the ones you use most ?


> When you still use VC6 from 10 years ago, you don't profit from the
> better optimizations today's compiler can do for you.
>

Of course, what you guys seems not to realize is that this has a price
which may not be small.

Let's take another point view (I'm making up the story).

Suppose you're the boss of a small firm which delivers software in a
highly specialized field (say, structural engineering).
Your application has evolved over a decade and reached a steadly gross
revenue of $200,000 per year including new customers and maintenance.

The incomes allowed you to hire two programmes which work with you full
time. One day one of them comes up with the idea of upgrading the
compiler for increased benefits, although it's not immediately clear
which they are.

You perform a quick analysis and estimate the time in 3 months to
migrate the application and another 2 months for testing that everything
it's fine. It may be safe to account for another month due to Murphy's law.
Conclusion, you forecast a six months stop in development due to
code/environment migration and testing, which translates roughly in a
$100,000 cost.

You quickly realize that one or probably both programmers will loose
their job if you agree with the upgrade.

Would you still believe it's worth profitting the better optimization
today compilers can do for you ?

Regards,
Giuliano Bertoletti.


==============================================================================
TOPIC: Processing a text file
http://groups.google.com/group/comp.lang.c++/t/56af946467295a55?hl=en
==============================================================================

== 1 of 3 ==
Date: Sat, Mar 28 2009 8:02 am
From: Stephan Ceram


I need to do some post-processing of a text file in my C++ application.
In detail, I have to check if the last line of the text file ends with the
string "done" or "finished". If not, the last line must be removed from
the text file. How can I achieve this?

Regards,
Stephan

== 2 of 3 ==
Date: Sat, Mar 28 2009 12:26 pm
From: "Default User"


Stephan Ceram wrote:

> I need to do some post-processing of a text file in my C++
> application. In detail, I have to check if the last line of the text
> file ends with the string "done" or "finished". If not, the last line
> must be removed from the text file. How can I achieve this?

You have three things to do.

1. Find the last line of the file.
2. Check the contents of that line.
3. Delete the line if necessary.


Now, what have you done so far? Do you know how to open a file? Read
lines of text? Search within lines?

Usually, people here won't write code from scratch for you. Post your
effort and explain where you having trouble. If you can't even start
the job, then it's beyond your capabilities and you need to fall back a
bit.

Brian

--
Day 53 of the "no grouchy usenet posts" project


== 3 of 3 ==
Date: Sat, Mar 28 2009 12:32 pm
From: Victor Bazarov


Stephan Ceram wrote:
> I need to do some post-processing of a text file in my C++ application.

Why do you call it "post"-processing? "Post" means "after", doesn't it?
After what?

> In detail, I have to check if the last line of the text file ends with the
> string "done" or "finished". If not, the last line must be removed from
> the text file. How can I achieve this?

Get the size of the file. Seek to 10 characters from the end (see
"SEEK_END"), then read the 10 characters and perform the comparison from
the end backwards. If the first (the last) character isn't a '\n', then
your file ends on an incomplete line, test fails. If so, keep checking.
You should fail if you don't see 'e', 'n', 'o', 'd', '\n', or 'd',
'e', ..., 'f', '\n'.

What does this have to do with C++? Or do you not know how to seek in a
file and how to extract characters? RTFM on 'seekg' and 'get', or, if
you use 'FILE*' for your IO, see 'fseek' and 'fread'.

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

==============================================================================
TOPIC: Unignorable return value
http://groups.google.com/group/comp.lang.c++/t/3b14b8ccfba9854c?hl=en
==============================================================================

== 1 of 4 ==
Date: Sat, Mar 28 2009 8:35 am
From: "Thomas J. Gritzan"


gw7rib@aol.com schrieb:
> If I have a function returning int, then I am free to ignore that
> return value. For instance:
>
> int fun(void);
> x = fun(); // valid
> fun(); // valid
>
> If I want the former form to be invalid, I can instead make the
> function of type void:
>
> void fun(void);
> x = fun(); // invalid
> fun(); // valid

I don't know a way to do this at compile time, but you could return an
object, that will throw an exception or assert() in the destructor, if
you didn't call a specific get() function on it.

But the problem below is not something where I would use this.

> The reason I would like such a thing is this.
[...]

In short, you want a 'lazy repaint' for your GUI windows.

The usual way is, AFAIK, to have a 'needs repaint' flag (sometimes
called 'is_dirty') in all your windows/widgets, which is set to true, if
this window needs to repaint itself.
Your GUI message queue then processes all its messages, and when there
are no more messages, that is, when the application is idle, it repaints
all windows which have this flag set.

--
Thomas


== 2 of 4 ==
Date: Sat, Mar 28 2009 8:52 am
From: "Balog Pal"


<gw7rib@aol.com>

> The reason I would like such a thing is this. I am writing a program
...
> present the routine handling the change of file name will repaint the
> note if necessary. But if the user makes both changes then this can
> result in the note being repainted twice, the first time incorrectly
> as it has not yet taken all the changes into account.

Does not sound so bad. Though you must use some interesting system. I.e. on
windows all you do is 'invalidate' the window or an area. Paint will be
called eventually, after all the things done, and will figure out what to
draw from the latest state. So multiple invalidates still result in a single
paint without anyone's work. Unless certainly the repaint is forced by
UpdateWindow() or alike, that is not suggested.

> So I am
> considering moving the repaint up into the edit properties routine, so
> that there will be one repaint afterwards if either or both of the
> subroutines say it is necessary. Since the subroutines thus lose
> direct control over whether the repaint happens, I would like to
> ensure that their return value (indicating whether it is required) is
> not ignored to make it harder for me to mess this up.

This sounds like a bad design. If the user calls 'ChangeText()' or
ChangePicture(), he wants an action. Not a query whether he shall paint or
not. I'd make them void functions.
And if repaint is needed in a different way than suggested above, the class
itself can handle a 'dirty' flag that is set by any function calling for a
repaint. Then you can issue an Update() working from those flags (possibly
doing nothing). With some luck you can issu that autmaticly somewhere, if
not, you can tell the user that it's obligatory at some points -- though
must be called mandatorily, not forcig to twiddle with conditional logic,
etc.

>
> Any thoughts welcome!
>
> Thanks.
> Paul.


== 3 of 4 ==
Date: Sat, Mar 28 2009 12:49 pm
From: Marcel Müller


Victor Bazarov wrote:
>> unignorable int fun(void);
>> x = fun(); // valid
>> fun(); // invalid
>
> There is no way. Even if you force the caller of the function to get
> the value, what makes you think the caller is going to do anything about
> the value it gets?
>
> int unignorable fun();
> ...
> int dummy = fun();
> // go on with our processing without paying attention to 'dummy'

This will raise a warning about dummy on many platforms.


Marcel


== 4 of 4 ==
Date: Sat, Mar 28 2009 12:59 pm
From: Marcel Müller


Hi!

gw7rib@aol.com wrote:
> But supose I have a function where I don't want the return value to be
> ignored. Is there any way I can do this? For instance:
>
> unignorable int fun(void);
> x = fun(); // valid
> fun(); // invalid

void fun(int unignorable& retval);
fun(x);
fun(); // invalid

[...]
> showing the text or vice versa, it again will need repainting. At
> present the routine handling the change of file name will repaint the
> note if necessary. But if the user makes both changes then this can
> result in the note being repainted twice, the first time incorrectly
> as it has not yet taken all the changes into account.

Add
bool repaint;
to your object and post a request to your message queue, every time the
repaint flag turns to true. The request handler checks and clears
repaint. This will merge the repaint in most cases. In an multi-threaded
application you may do this with atomic instructions.
Of course, you have to take care of the objects lifetime when doing this
kind of asynchronous painting. But GUI applications usually have to do
this anyway.


> So I am
> considering moving the repaint up into the edit properties routine, so
> that there will be one repaint afterwards if either or both of the
> subroutines say it is necessary.

Bad idea to intermix the presentation layer with the controller logic.


Marcel

==============================================================================
TOPIC: Standard C++ way to generate a Jump Table ???
http://groups.google.com/group/comp.lang.c++/t/7686e7082cfac191?hl=en
==============================================================================

== 1 of 3 ==
Date: Sat, Mar 28 2009 10:21 am
From: Puppet_Sock


On Mar 27, 6:55 am, "Peter Olcott" <NoS...@SeeScreen.com> wrote:
[snip]
> I am shooting for maximum speed, thus function call overhead
> is not acceptable.

I've seen the name Peter Olcott about this group, so likely
all I've got to say is old news to you. This is mostly for
newbies who may be lurking.

Maybe what you need is to do this small portion in assembler then.

Also, before you go to that effort, I'd suggest you want to
get some good profiling tools and measure performance. Make
sure you really are losing time at the call, and that it would
gain you a path to a "win" by decreasing it.

And before you do *that* you should define, with numeric values,
what a "win" woould be. "Maximum speed" is rarely a reasonable
spec. For example, does speed over-ride correct results? In some
cases it might, but certainly not every case. If you line up
your spec requirements, you may then find that instead of
"maximum" speed, you have "total program execuation time is
less than <so many> seconds" or "time the user waits for a
response in this case is less than <so much time>" etc.

If you line up your specs that way, you may find that using a
profiling tool tells you that you can't possibly get to a win
by optimizing this call sequence. Or you may find that you
can get the required values with a less nasty optimization
in some other part of the code. Maybe you can even re-factor
something so this call goes away, or becomes something else
that is easier, in context, to optimize.

Or possibly all I've said is irrelevant due to other constraints.
Maybe you must use this call form due to existitng libraries
or legacy code or some such. Software is usually written under
such constraints.
Socks


== 2 of 3 ==
Date: Sat, Mar 28 2009 2:40 pm
From: blargg.ei3@gishpuppy.com (blargg)


Peter Olcott wrote:
> blarg wrote:
> > Peter Olcott wrote:
[...]
> >> I can tell from the quality of the generated assembly
> >> language that there is no possible further improvement of
> >> this fundamental control flow construct. (Within the
> >> binding constraint of the machine architecture).
> >
> > I doubt it. What about eliminating the jump table and
> > calculating the destination as PC+(N<<shift), so that
> > each case statement is some power of 2 from the previous?
> > There's always room for improvement, and the
> > micro-improvements are generally beyond a compiler.
>
> Infeasible, more cases than bits, and memory use would grow
> absurdly fast. There is no feasible improvement within the
> binding constraints.

No human can reliably claim that there is "no feasible improvement". I
don't care what the software; there's always some improvement that some
other person can see that you can't.

If the more common cases only use a few lines of code, while the
less-common ones use more, you can use a small shift and have branches to
the larger code for the less-common cases. But you've been so secretive
about the code, that it's no fun to play such a hypothetical game (I'm
interested in offering more ideas, in private if you like).


== 3 of 3 ==
Date: Sat, Mar 28 2009 2:46 pm
From: blargg.ei3@gishpuppy.com (blargg)


Peter Olcott wrote:
[...]
> The way that standard C++ could handle my issue without
> having to resort to vendor specific extensions to the
> language would be if all enumeration type values could only
> be specified in terms of their enumeration names. Specifying
> an enumeration value as any integer would be caught as a
> syntax error.

That's the way it is, only one can cast from an integer to an enmueration:

enum E { min = 0, max = 15 };

E e = 0; // error
E e = (E) 0; // OK

This is necessary when type information is lost, particularly when saving
enumeration values to disk and later loading them. Unforfunately, the
current wording also allows use of values for which there is no named
constant, for example

E e = (E) 7; // OK, and well-defined
assert( e == 7 ); // passes

> The compiler would be free to map these names to a
> contiguous set of integer values beginning with zero.
> Whenever a switch statement would be specified using an
> enumeration, the compiler would know that it would not have
> to insert the extra code to test for out-of-range values,
> because all out-of-range values would be reported as syntax
> errors at compile time.

This seems a round-about way of achieving a more general
constraint-specification system. I like my solution, as it doesn't require
any new language mechanisms:

if ( n < 0 || n > 7 ) // tell compiler that n is never outside this range
*(int*) 0 = 0; // undefined behavior

==============================================================================
TOPIC: Question about reading from stream.
http://groups.google.com/group/comp.lang.c++/t/52af4ea746edf596?hl=en
==============================================================================

== 1 of 2 ==
Date: Sat, Mar 28 2009 10:21 am
From: coal@mailvault.com


On Mar 28, 6:09 am, James Kanze <james.ka...@gmail.com> wrote:
> On Mar 27, 8:31 pm, c...@mailvault.com wrote:
>
>
>
>
>
> > On Mar 27, 4:03 am, James Kanze <james.ka...@gmail.com> wrote:
> > > On Mar 26, 8:44 pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> > >     [...]
> > > It depends on the application.  What if it's a compiler?  Or a
> > > Unix filter like grep or sed?  For that matter, if clients share
> > > no data directly, there are strong arguments for starting up a
> > > new instance of a server for each connection;
> > I think the arguments in favor of a long running server are
> > stronger than those against it in the case of compilers.
> > The design and implementation have to be such that separate
> > requests do not interfere with each other.  There are some
> > steps that you can take that help in that area, but don't
> > require anything like a new process and a completely fresh
> > start.  Besides the basic efficiencies afforded, there's
> > a lot of basic information that doesn't change between
> > requests.  Why rescan/prepare for <vector> billions of
> > times when it doesn't change one little bit?  It surprises
> > me that you question this given what I know of your
> > background.
>
> The contents of std::vector are data, not code, and don't
> evolve.  There's nothing wrong with having it cached somewhere,
> maybe loaded by mmap, but just keeping a server up so that
> compilations won't have to reread it seems a bit overkill.
> (There's also the fact that formally, the effects of compiling
> an include file depend on what macros are defined beforehand.
> Even something like std::vector: the user doesn't have the right
> to define any macros which might conflict, but most
> implementations have two or more different versions, depending
> on the settings of various macros.)
>

In that case, it might make sense to only have the most common
case cached and reparse the file if someone is doing something
somewhat unusual. That's how I would probably start to support
the idea.

> Anyway, my comments were, largely, based on the way things are,
> rather than how they could be.  I've not actually given the idea
> of implementing a compiler as a server much thought, but today's
> compilers are not implemented that way.  I certainly don't want
> to imply that things have to be like they are.
>
> > > you don't want
> > > start up time to be too long there, either.
> > It has to done efficiently.  Single-run compilers are a
> > luxury that is fading.  I harp on this, but gcc needs to
> > be overhauled twice.  First a rewrite in C++ and then a
> > rewrite to be an on line compiler.  The first phase of
> > the on line part could be to simply run once and exit
> > after each request.  That though would have to be
> > replaced by a real server approach that runs like a
> > champ.  They are so far away from this it isn't even
> > funny.
>
> So are most of the other compiler implementers, as far as I
> know.

Well, I think some C++ compilers are written in C++ so they
would be in better shape (potentially) in my opinion than gcc.
But probably few if any of them are being rewritten to be
on line servers. I believe that will change. I read an
article in the Wall Street Journal about how some companies
are giving away their software because over the past 18 months
their software stopped selling. That's not exactly news
except that the practice of giving away software is spreading
and companies that have previously been immune to some of the
market forces are now having to play by the rules that the
smaller guys accept.

>
> I'm not too sure what the server approach would by us in most
> cases, as opposed, say, to decent pre-compiled headers and
> caching.  (If I were implementing a compiler today, it would
> definitely make intensive use of caching; as you say, there's no
> point in reparsing std::vector everytime you compile.)

People have mentioned on here that it is a headache to
manage more than a couple of compilers on your own system.
It buys efficiency though mainly. A new release is made in
one place and then anyone may use it without having to down-
load and install it. This avoids the case where a user
accidentally corrupts his installation and then has to
download and reinstall the compiler. The main advantage
might be the speed with which new releases and fixes can be
made available.


>
> The "xxx on line" pages I know of for other compilers are just
> front ends, which run the usual, batch mode compiler.  It would
> be trivial for someone to do this with g++---if Comeau wanted,
> for example, I doubt that it would take Greg more than a half a
> day to modify his page so you could use either his compiler or
> g++ (for comparison purposes?).

Someone will probably do it eventually.

>
> I'm certainly in favor of making compilers accessible on-line,
> but that's a different issue.  No professional organization
> would use such a compiler, except for test or comparison
> purposes.
>

What about using it within their intranet? I think the choice
comes down to using a service for free on a public site or
paying for it and using it behind a firewall. Individuals and
smaller organizations will probably go with the free approach
and may use some techniques to protect their work.


Brian Wood
Ebenezer Enterprises
www.webEbenezer.net


== 2 of 2 ==
Date: Sat, Mar 28 2009 12:20 pm
From: coal@mailvault.com


On Mar 28, 12:21 pm, c...@mailvault.com wrote:
>
> What about using it within their intranet?   I think the choice
> comes down to using a service for free on a public site or
> paying for it and using it behind a firewall.   Individuals and
> smaller organizations will probably go with the free approach
> and may use some techniques to protect their work.

I would like to point out a couple more things. Those that
can afford to buy the service and use it privately are paying
a high price for the privacy because they have to pay for
managing/maintaining it themselves. They have to patch it
whenever they want to pick up a fix. They better be a very
well run organization in order to make that work. And say
Comeau had an on line version of his compiler. How can he
prevent someone who works for an organization who has bought
a license from him from copying his software and then trying
to make some money by making illegal copies of it? It's tough
to stop. This is a reason why Google and others who have the
on line versions of programs similar to Microsoft Office are
in better shape in my opinion than Microsoft going forward.
Microsoft drags it's feet in developing/promoting their on
line versions.

In my case, I don't trust most politicians or governments
to do the right thing by me. So I make the service
available for free on line, but don't think it's a good
idea to sell it to someone because it might be illegally
copied after that. Software piracy/theft was a problem
before the recent economic problems, so I doubt matters
will improve and they may get worse. The truth is the
Chinese, Indian, Russian, etc. governments just don't
care about an American boy like me. They gotta think
about helping their people out. If that means
betraying me or Microsoft, that's OK with them.


Brian Wood
Ebenezer Enterprises
www.webEbenezer.net

==============================================================================
TOPIC: Is this a good reference-counting smart pointer class?
http://groups.google.com/group/comp.lang.c++/t/41558400ad1ce160?hl=en
==============================================================================

== 1 of 4 ==
Date: Sat, Mar 28 2009 10:44 am
From: douglas


On Mar 28, 1:12 am, Juha Nieminen <nos...@thanks.invalid> wrote:
> Protoman wrote:
> > explicit SmrtPtr<T>(T* obj=0):ptr(obj),DataBase(new SmrtPtrDB){}
> > SmrtPtr<T>(const SmrtPtr<T>& rhs):ptr(rhs.ptr),DataBase(new
> > SmrtPtrDB(rhs.DataBase->status())) {DataBase->add();}
>
>   No, this definitely doesn't work.
>
>   You are *not* sharing the 'DataBase' instance between the 'SmrtPtr'
> copies pointing to the same object. In other words, each instance of
> 'SmrtPtr' has its own instance of 'DataBase'. Basically there's no
> difference between what you have done there and having a 'SmrtPtrDB'
> instance directly as a member variable (rather than it being allocated
> dynamically).
>
>   You are copying the reference count from 'rhs' to the newly-created
> instance of 'DataBase' in the copy constructor. How do you think it's
> going to notice if that other 'SmrtPtr' is destroyed? It retains no
> connection to it whatsoever, so there's no way it can notice that it has
> disappeared.
>
>   Moreover, that other 'SmrtPtr' instance is not going to notice that a
> new 'SmrtPtr' instance was created to point to the same object. The
> reference count of the former will be unmodified. Thus when the former
> is destroyed, it will delete the object, and not the new 'SmrtPtr'
> object will point to deleted memory.

So, how do I fix it?


== 2 of 4 ==
Date: Sat, Mar 28 2009 1:02 pm
From: Marcel Müller


douglas wrote:
> So, how do I fix it?

You either need an intrusive reference count or a manager object that is
shared by all instances of the smart pointer that point to the same object.

I prefer the first, if I have the choice.


Marcel


== 3 of 4 ==
Date: Sat, Mar 28 2009 2:11 pm
From: Kram


On Mar 28, 3:32 am, Protoman <Protoman2...@gmail.com> wrote:
> Is this a good reference-counting smart pointer class?
>
> // begin code
> -------------------------------------------------------------------------------------------------------------------
> class SmrtPtrDB
> {
> public:
> SmrtPtrDB(int status=1):num(status){}
> SmrtPtrDB(const SmrtPtrDB& rhs):num(rhs.num){}
> ~SmrtPtrDB(){}
> void add(){num++;}
> void sub(){num--;}
> int status(){return num;}
> private:
> int num;
>
> };
>
> class NullPtr{};
>
> template<class T>
> class SmrtPtr
> {
> public:
> explicit SmrtPtr<T>(T* obj=0):ptr(obj),DataBase(new SmrtPtrDB){}
> SmrtPtr<T>(const SmrtPtr<T>& rhs):ptr(rhs.ptr),DataBase(new
> SmrtPtrDB(rhs.DataBase->status())) {DataBase->add();}
> ~SmrtPtr<T>()
> {
> DataBase->sub();
> if(DataBase->status()==0)
> {delete ptr; delete DataBase;}
> else {delete DataBase;}}
>
> void operator=(T* val)
> {
> SmrtPtr<T> temp(val);
> swap(temp);}
>
> SmrtPtr<T>& operator=(const SmrtPtr<T>& rhs)
> {
> SmrtPtr<T> temp(rhs);
> swap(temp);
> return *this;}
>
> bool operator==(const SmrtPtr<T>& rhs)const {if(ptr==rhs.ptr)return
> true;else return false;}
> bool operator!=(const SmrtPtr<T>& rhs)const {if(ptr!=rhs.ptr)return
> true;else return false;}
> bool operator<=(const SmrtPtr<T>& rhs)const {if(ptr<=rhs.ptr)return
> true;else return false;}
> bool operator>=(const SmrtPtr<T>& rhs)const {if(ptr>=rhs.ptr)return
> true;else return false;}
> int status(){return DataBase->status();}
> T& operator*()const {if(ptr==0)throw NullPtr();else return *ptr;}
> T* operator->()const {if(ptr==0)throw NullPtr();else return ptr;}
> operator T*()const {if(ptr==0)throw NullPtr();else return ptr;}
> private:
> void swap(SmrtPtr<T>& rhs)
> {
> std::swap(DataBase,rhs.DataBase);
> std::swap(ptr,rhs.ptr);}
>
> mutable SmrtPtrDB* DataBase;
> T* ptr;};
>
> //end of code
> ---------------------------------------------------------------------------------------------------------------------------------
>
> How do I improve this class? Is there anything "wrong" with it?

It seems like you're design is to create a database that keep track of
addresses being referenced by pointers in a class. That way you can
know how many references there are to a memory address. The problem is
you create a new copy of the database for each pointer, you need to
look into the Singleton method for the database, and use the factory
method to generate pointers. This factory can either contain or
reference the Database and that way you ensure only one shared
database.


== 4 of 4 ==
Date: Sat, Mar 28 2009 3:04 pm
From: douglas


On Mar 28, 2:11 pm, Kram <cmayn...@gmail.com> wrote:
> On Mar 28, 3:32 am, Protoman <Protoman2...@gmail.com> wrote:
>
>
>
>
>
> > Is this a good reference-counting smart pointer class?
>
> > // begin code
> > ---------------------------------------------------------------------------­----------------------------------------
> > class SmrtPtrDB
> > {
> > public:
> > SmrtPtrDB(int status=1):num(status){}
> > SmrtPtrDB(const SmrtPtrDB& rhs):num(rhs.num){}
> > ~SmrtPtrDB(){}
> > void add(){num++;}
> > void sub(){num--;}
> > int status(){return num;}
> > private:
> > int num;
>
> > };
>
> > class NullPtr{};
>
> > template<class T>
> > class SmrtPtr
> > {
> > public:
> > explicit SmrtPtr<T>(T* obj=0):ptr(obj),DataBase(new SmrtPtrDB){}
> > SmrtPtr<T>(const SmrtPtr<T>& rhs):ptr(rhs.ptr),DataBase(new
> > SmrtPtrDB(rhs.DataBase->status())) {DataBase->add();}
> > ~SmrtPtr<T>()
> > {
> > DataBase->sub();
> > if(DataBase->status()==0)
> > {delete ptr; delete DataBase;}
> > else {delete DataBase;}}
>
> > void operator=(T* val)
> > {
> > SmrtPtr<T> temp(val);
> > swap(temp);}
>
> > SmrtPtr<T>& operator=(const SmrtPtr<T>& rhs)
> > {
> > SmrtPtr<T> temp(rhs);
> > swap(temp);
> > return *this;}
>
> > bool operator==(const SmrtPtr<T>& rhs)const {if(ptr==rhs.ptr)return
> > true;else return false;}
> > bool operator!=(const SmrtPtr<T>& rhs)const {if(ptr!=rhs.ptr)return
> > true;else return false;}
> > bool operator<=(const SmrtPtr<T>& rhs)const {if(ptr<=rhs.ptr)return
> > true;else return false;}
> > bool operator>=(const SmrtPtr<T>& rhs)const {if(ptr>=rhs.ptr)return
> > true;else return false;}
> > int status(){return DataBase->status();}
> > T& operator*()const {if(ptr==0)throw NullPtr();else return *ptr;}
> > T* operator->()const {if(ptr==0)throw NullPtr();else return ptr;}
> > operator T*()const {if(ptr==0)throw NullPtr();else return ptr;}
> > private:
> > void swap(SmrtPtr<T>& rhs)
> > {
> > std::swap(DataBase,rhs.DataBase);
> > std::swap(ptr,rhs.ptr);}
>
> > mutable SmrtPtrDB* DataBase;
> > T* ptr;};
>
> > //end of code
> > ---------------------------------------------------------------------------­------------------------------------------------------
>
> > How do I improve this class? Is there anything "wrong" with it?
>
> It seems like you're design is to create a database that keep track of
> addresses being referenced by pointers in a class. That way you can
> know how many references there are to a memory address. The problem is
> you create a new copy of the database for each pointer, you need to
> look into the Singleton method for the database, and use the factory
> method to generate pointers. This factory can either contain or
> reference the Database and that way you ensure only one shared
> database.- Hide quoted text -
>
> - Show quoted text -

I know the Singleton pattern, but what's the factory pattern? Can you
give me an example?

==============================================================================
TOPIC: how to convert a binary file to base64?
http://groups.google.com/group/comp.lang.c++/t/7aa8fbb30055a8db?hl=en
==============================================================================

== 1 of 2 ==
Date: Sat, Mar 28 2009 11:27 am
From: Cristiano


Hello,

I'm trying to send as an attachment a zip file, in my C++ application.

To send using SMTP protocol, I'm trying to cripting the zip file to
base64 code.

I'm using this code to convert: http://www.adp-gmbh.ch/cpp/common/base64.html

The code convert the zip file in base64 code and I can send the e-
Mail.

But, when I receive the e-Mail, I download the zip file and when I try
to open it, I have a error mesage "the zip file is corrupted".

I got this error just using zip files. Whan I attach text files, this
erros doesn't exists.

Please, can you help me with this?

I'm converting the zip file like this:

============================================================
string copyFileToString(string filename)
{
string retorno;

FILE *from;

from = fopen (filename.c_str(),"rb");

char ch;
/* copy the file */
while(!feof(from))
{
ch = fgetc(from);
if(ferror(from))
{
//printf("Error reading source file.\n");
exit(1);
}
if(!feof(from))
retorno += ch;
}

if(fclose(from)==EOF)
{
//printf("Error closing source file.\n");
exit(1);
}
return retorno;
}

//...

int main()
{

//...

string file = copyFileToString("sample.zip");
string fileBase64 = base64_encode(reinterpret_cast<const unsigned
char*>(file.c_str()), file.length());

//...

}
============================================================

So, am I doing some mistake ?

Thank you.


--
Cristiano


== 2 of 2 ==
Date: Sat, Mar 28 2009 1:58 pm
From: Kram


On Mar 28, 2:27 pm, Cristiano <crixti...@gmail.com> wrote:
> Hello,
>
> I'm trying to send as an attachment a zip file, in my C++ application.
>
> To send using SMTP protocol, I'm trying to cripting the zip file to
> base64 code.
>
> I'm using this code to convert:http://www.adp-gmbh.ch/cpp/common/base64.html
>
> The code convert the zip file in base64 code and I can send the e-
> Mail.
>
> But, when I receive the e-Mail, I download the zip file and when I try
> to open it, I have a error mesage "the zip file is corrupted".
>
> I got this error just using zip files. Whan I attach text files, this
> erros doesn't exists.
>
> Please, can you help me with this?
>
> I'm converting the zip file like this:
>
> ============================================================
> string copyFileToString(string filename)
> {
>   string retorno;
>
>   FILE *from;
>
>   from = fopen (filename.c_str(),"rb");
>
>   char ch;
>   /* copy the file */
>   while(!feof(from))
>   {
>     ch = fgetc(from);
>     if(ferror(from))
>     {
>       //printf("Error reading source file.\n");
>       exit(1);
>     }
>     if(!feof(from))
>       retorno += ch;
>   }
>
>   if(fclose(from)==EOF)
>   {
>     //printf("Error closing source file.\n");
>     exit(1);
>   }
>   return retorno;
>
> }
>
> //...
>
> int main()
> {
>
> //...
>
>     string file = copyFileToString("sample.zip");
>     string fileBase64 = base64_encode(reinterpret_cast<const unsigned
> char*>(file.c_str()), file.length());
>
> //...
>
> }
>
> ============================================================
>
> So, am I doing some mistake ?
>
> Thank you.
>
> --
> Cristiano

This forum is for questions about the C++ language and not about
individual libraries, however I would think the error has to do with
reading in the zip file as a text file instead of a binary file. Read
the documentation on fopen, I think that will help.

==============================================================================
TOPIC: Design question: polymorphism after object creation
http://groups.google.com/group/comp.lang.c++/t/b748f0f3d941a3ba?hl=en
==============================================================================

== 1 of 2 ==
Date: Sat, Mar 28 2009 12:33 pm
From: Marcel Müller


Hi,

I am seeking for a neat solution for the following problem:

There are objects of different types with a common base class, let's say
folders and files (although that does not completely hit the nail on the
head). These objects have a common primary key, the full qualified path.
But the polymorphic type of the objects emerges only *after* the object
has been referenced. See below.

The implementation currently uses a static instance repository of all
objects. The objects are reference counted and only instantiated by a
global factory function. Two objects with the same key must not coexists
in memory.

// int_ptr<T> is mostly the same than boost::intrusive_ptr<T>

class Base;

class Repository
{ ...
public:
// Singleton!
static Repository Instance;

// Seek whether an object is already loaded.
// May return NULL
int_ptr<Base> FindByURL(const string& url);
// FACTORY! Get a new or an existing instance of this URL.
// Does not return NULL
int_ptr<Base> GetByURL(const string& url);
};

When instantiating the objects by their path (e.g. while enumerating a
folders content) the exact type of the object is not yet known. Only if
the application requests certain information about the object, the type
has to be specialized. Unfortunately this is not always a cheap
operation. In fact it cannot be done synchronously at the time the
factory is called.

class Base
{public:
const string URL;

enum InfoFlags // Different kind of information
{ IF_None = 0,
IF_Metadata = 1,
IF_Content = 2,
IF_Type = 4, // The polymorphic type of the object
...
};

// Retrieve information asynchronously if the requested information is
// not yet available. The function returns the flags of the requested
// information that is immediately available.
// For all the missing bits you should wait for the matching
// InfoChange event to get the requested information.
// If no information is yet available, the function returns IF_None.
// Of course, you have to register the event handler before the call
// to EnsureInfoAsync. If EnsureInfoAsync returned all requested bits
// the InfoChange event is not raised as result of this call.
virtual InfoFlags EnsureInfoAsync(InfoFlags what);

// Observable pattern
event<InfoFlags> InfoChange;

// Retrieve the current meta information. Returns only valid info
// if EnsureInfoAsync has returned IF_Metadata or the InfoChange event
// has fired with IF_Metadata set.
virtual Metadata GetMetadata() const;
...

protected:
Base(const string& url) : URL(url) {}
};

class File : public Base
{public:
virtual Metadata GetMetadata() const;
...

protected:
File(const string& url) : Base(url) {}
friend class Repository; // For the factory
};

class Folder : public Base
{public:
virtual Metadata GetMetadata() const;
...

protected:
Folder(const string& url) : Base(url) {}
friend class Repository; // For the factory
};


At the very first no information is available about the object. Only if
some information is requested, I/O operations take place to specialize
the object. Of course, once specialized, the type will never change.

Now the problem is at the time the object is created, I have only an
empty shell, that forwards EnsureInfoAsync to plug-ins to determine the
effective type of the object. But at this time observers are already
registered and strong references to the object are around in the
application. Therefore it is not sufficient to atomically replace the
generalized object by the specialized one in the repository.

The only idea I have so far is to introduce another level of indirection
and replace all occurrences of int_ptr<Base> by int_ptr<BaseProxy>.
BaseProxy contains the int_ptr<Base> and forwards the functionality. But
this is neither clear nor of high-performance. Furthermore some services
have to be provided by BaseProxy only, e.g. the observable pattern or
the synchronization. This causes a briskly interaction between BaseProxy
and Base, although these classes are unrelated from the C++ point of
view. No well designed OOP.

So, are there any other ideas to implement something like that?


Marcel


== 2 of 2 ==
Date: Sat, Mar 28 2009 3:19 pm
From: "Balog Pal"


"Marcel Müller" <news.5.maazl@spamgourmet.com>

> I am seeking for a neat solution for the following problem:
>
> There are objects of different types with a common base class, let's say
> folders and files (although that does not completely hit the nail on the
> head). These objects have a common primary key, the full qualified path.
> But the polymorphic type of the objects emerges only *after* the object
> has been referenced. See below.
[...]

I get this, but the following seem contradictory, especially the observer
part.
If the object is not there yet why on earth is it observed?

From my limited understanding of the problem, I'd have something like:

map<string, shared_ptr<Base> > repository;

As the only info up front is PK, in this phase you just put that in the map,
the ptr is null, signaling the not-accessed state.

When access comes, you have the extra info, create the object by factory and
put it in the ptr.

If your initial info is more elaborate, you can create a struct of it, and
use instead of string in the map. To avoid duplication, the object body
can have a pointer to the PK part, passed in ctor. If the object lives only
in this repository, and it is a map, the nodes are stable. (certainly I
would internally firewall the access to PK by a function, so later it can be
simply converted in a local copy, or a shared_ptr instead of raw, etc...)


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

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: