Friday, March 27, 2009

comp.lang.c++ - 26 new messages in 11 topics - digest

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

comp.lang.c++@googlegroups.com

Today's topics:

* Standard C++ way to generate a Jump Table ??? - 5 messages, 2 authors
http://groups.google.com/group/comp.lang.c++/t/7686e7082cfac191?hl=en
* float and double precision - 5 messages, 4 authors
http://groups.google.com/group/comp.lang.c++/t/b4c58ab5204ef5a3?hl=en
* Does anyone else wish the C++ standards committee would give us parity with
other programming languages? - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/65479c8a9a474e0b?hl=en
* disadvantages of using STL - 3 messages, 2 authors
http://groups.google.com/group/comp.lang.c++/t/fb1f5fcc56ce965e?hl=en
* Using type prefixes with floating point constants - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/bb3e3831ff763cf0?hl=en
* CRTP, member typedefs and access control - 3 messages, 3 authors
http://groups.google.com/group/comp.lang.c++/t/a3b80f88997409de?hl=en
* Techniques to reduce executable size - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/975f1b54c967ffef?hl=en
* fstream - write a file - 2 messages, 2 authors
http://groups.google.com/group/comp.lang.c++/t/f149a5a9c1a12802?hl=en
* Question about reading from stream. - 1 messages, 1 author
http://groups.google.com/group/comp.lang.c++/t/52af4ea746edf596?hl=en
* Corrected: Using type suffixes with floating point constants - 1 messages, 1
author
http://groups.google.com/group/comp.lang.c++/t/e4b6beec5748ef9f?hl=en
* operator overloading simple question - 3 messages, 3 authors
http://groups.google.com/group/comp.lang.c++/t/f176f1743eb21cb4?hl=en

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

== 1 of 5 ==
Date: Fri, Mar 27 2009 12:11 am
From: Paavo Helde


"Peter Olcott" <NoSpam@SeeScreen.com> kirjutas:

> This is as close as I could get to generating the equivalent
> of an assembly language jump table:
>
> switch(N)
> {
> case 0:
> case 1:
> case 2:
> case 3:
> case 4:
> case 5:
> case 6:
> case 7:
> }
>
> mov eax, DWORD PTR _N$[esp-4]
> cmp eax, 7
> ja SHORT $LN1_TestSpeed
> jmp DWORD PTR $LN14_TestSpeed[eax*4]
>
> I am looking for a way to be able to specify C++ code such
> that the second and third line of the assembly language
> would not be generated. The only way that I can think to do
> this is to delete the two lines and compile it as assembly
> language.

Out of curiosity - have you measured how much effect deleting these two
lines would give you? (Presuming of course there are some non-empty cases,
otherwise the compiler should optimize the whole construction away.)

> Are there any possible standard C++ ways to do this?
>

Standard C++ requires the code to work also if N is outside of [0,7], so it
cannot strip away the code for that. You could try to declare N as unsigned
char and provide all 256 cases.

FWIW, MSVC++ provides the __assume keyword as an extension, letting one to
tell the optimizer things like that. The example in the MSDN documentation
is exactly about optimizing out the default branch of a switch.

Paavo

== 2 of 5 ==
Date: Fri, Mar 27 2009 12:32 am
From: Paavo Helde


Sam <sam@email-scan.com> kirjutas:

> Peter Olcott writes:
>
>> This is as close as I could get to generating the equivalent
>> of an assembly language jump table:
>>
>> switch(N)
>> {
>> case 0:
>> case 1:
>> case 2:
>> case 3:
>> case 4:
>> case 5:
>> case 6:
>> case 7:
>> }
>>
>> mov eax, DWORD PTR _N$[esp-4]
>> cmp eax, 7
>> ja SHORT $LN1_TestSpeed
>> jmp DWORD PTR $LN14_TestSpeed[eax*4]
>>
>> I am looking for a way to be able to specify C++ code such
>> that the second and third line of the assembly language
>> would not be generated. The only way that I can think to do
>> this is to delete the two lines and compile it as assembly
>> language.
>> Are there any possible standard C++ ways to do this?
>
> Well, if I understood you correctly:
>
> The only possible way you can hope to have the C++ compiler optimize
> away the comparison, with you still using standard C++ as your source,
> is for you replace your literal integer values with an enum type that
> contains only eight values, something like
>
> enum something {
> firstval=0,
> …
> lastval=7
> };
>
> Then, if you switch to an instance of the enumerated type, the C++
> compiler might be smart enough to realize that, technically, the
> switch specifies all possible values, so the boundary check is not
> needed.

Note that the enum values are required to accommodate any number fitting
into the same number of bits as the declared enum values. So the
optimization would be possible only if the enum provides dense values
from 0 up to some 2^N-1. This is the case here, indeed, so in principle,
the compiler ought to be able to strip out the boundary check, but I
would not bet my money on any existing compiler actually doing that.

Paavo

== 3 of 5 ==
Date: Fri, Mar 27 2009 12:42 am
From: Paavo Helde


"Ivan A. Kosarev" <ik@unicals.com> kirjutas:
>
> b) the set of values of the enumeration defined is not limited to values
> of the enumerators specified. A enumeration is able to represent any
> value from the range of values of its underlying type; see C++ 7.2 #6.

Not exactly - the clause you cite talks about bitfields:

<quote>
For an enumeration where emin is the smallest enumerator and emax is the
largest, the values of the enumeration
are the values of the underlying type in the range bmin to bmax, where bmin
and bmax are, respectively,
the smallest and largest values of the smallest bit-field that can store
emin and emax. It is possible to
define an enumeration that has values not defined by any of its
enumerators.
</quote>

Thus, for the example in OP post the underlying type could well be some 32-
bit int, whereas the valid values would be only those in range 0..7.

Paavo


== 4 of 5 ==
Date: Fri, Mar 27 2009 3:55 am
From: "Peter Olcott"

"Ivan A. Kosarev" <ik@unicals.com> wrote in message
news:NG_yl.124252$C87.95954@newsfe30.ams2...
> Peter Olcott wrote:
>> This is as close as I could get to generating the
>> equivalent of an assembly language jump table:
>>
>> switch(N)
>> {
>> case 0:
>> case 1:
>> case 2:
>> case 3:
>> case 4:
>> case 5:
>> case 6:
>> case 7:
>> }
>>
>> mov eax, DWORD PTR _N$[esp-4]
>> cmp eax, 7
>> ja SHORT $LN1_TestSpeed
>> jmp DWORD PTR $LN14_TestSpeed[eax*4]
>>
>> I am looking for a way to be able to specify C++ code
>> such that the second and third line of the assembly
>> language would not be generated. The only way that I can
>> think to do this is to delete the two lines and compile
>> it as assembly language.
>
> If it's known there are only these eight different values
> of N possible, then one of the case labels can be replaced
> with the default label so that your compiler will have no
> need to handle the default case implicitly.
>
> > Are there any possible standard C++ ways to do this?
>
> There is no a standard way to specify a statement to be a
> jump table. A call table, however, can be implemented with
> a table of function pointers.
>
> --

I am shooting for maximum speed, thus function call overhead
is not acceptable.


== 5 of 5 ==
Date: Fri, Mar 27 2009 3:57 am
From: "Peter Olcott"

"Paavo Helde" <paavo@nospam.please.ee> wrote in message
news:Xns9BDB5D92C2CDBnobodyebiee@216.196.109.131...
> "Peter Olcott" <NoSpam@SeeScreen.com> kirjutas:
>
>> This is as close as I could get to generating the
>> equivalent
>> of an assembly language jump table:
>>
>> switch(N)
>> {
>> case 0:
>> case 1:
>> case 2:
>> case 3:
>> case 4:
>> case 5:
>> case 6:
>> case 7:
>> }
>>
>> mov eax, DWORD PTR _N$[esp-4]
>> cmp eax, 7
>> ja SHORT $LN1_TestSpeed
>> jmp DWORD PTR $LN14_TestSpeed[eax*4]
>>
>> I am looking for a way to be able to specify C++ code
>> such
>> that the second and third line of the assembly language
>> would not be generated. The only way that I can think to
>> do
>> this is to delete the two lines and compile it as
>> assembly
>> language.
>
> Out of curiosity - have you measured how much effect
> deleting these two
> lines would give you? (Presuming of course there are some
> non-empty cases,
> otherwise the compiler should optimize the whole
> construction away.)
>
>> Are there any possible standard C++ ways to do this?
>>
>
> Standard C++ requires the code to work also if N is
> outside of [0,7], so it
> cannot strip away the code for that. You could try to
> declare N as unsigned
> char and provide all 256 cases.
>
> FWIW, MSVC++ provides the __assume keyword as an
> extension, letting one to
> tell the optimizer things like that. The example in the
> MSDN documentation
> is exactly about optimizing out the default branch of a
> switch.
>
> Paavo
>

Both suggestions are extremely helpful, thanks.

==============================================================================
TOPIC: float and double precision
http://groups.google.com/group/comp.lang.c++/t/b4c58ab5204ef5a3?hl=en
==============================================================================

== 1 of 5 ==
Date: Fri, Mar 27 2009 12:18 am
From: Carson Myers


would it be practical to use two int values, do you think?
Like in a class--one for the fractional part, and one for the whole-
number part-
that way I suppose it would be possible to avoid rounding errors since
the fractional part wouldn't really be treated as a fractional part,
but rather as a regular integer--you'd just have to worry about
handling the math and the behavior of the <1 portion of it yourself,
which would (I can imagine) be slow.

However I don't really understand how 0.1 could not be represented...
I've read about how it's a computer science problem, don't fully
understand but can vaguely grasp the concept (haven't read very much)--
but my compiler will still output 0.1 for float and double--if I
compiled "float x=0.1; std::cout<<x<<std::endl;" on another compiler
or system it may show something else? Unbelievable...


== 2 of 5 ==
Date: Fri, Mar 27 2009 12:34 am
From: tpl@eng.cam.ac.uk (Tim Love)


>However I don't really understand how 0.1 could not be represented...
>I've read about how it's a computer science problem, don't fully
>understand but can vaguely grasp the concept (haven't read very much)--
http://www.eason.com/library/math/floatingmath.pdf is often mentioned
(What Every Computer Scientist Should Know About Floating-Point Arithmetic)
though http://www.mathworks.com/support/tech-notes/1100/1108.html might be
an easier read.
It's worth knowing about even if you're not a Computer Scientist - spreadsheets exhibit the same trouble - you can't assume that 117/9 and 11.7/.9 are equal, or that adding a, b, and c (in that order) will give you the same answer as adding c, b, and a (in that order). Tough life, which is why programmers are paid so much.


== 3 of 5 ==
Date: Fri, Mar 27 2009 2:27 am
From: James Kanze


On Mar 26, 6:33 pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:
> carsonmy...@gmail.com wrote:
> > so, I hear that the float and double intrinsic types don't
> > have very good precision, due to the way which they store
> > the data--they are meant to be stored as 1.xxxxx right?

> Actually, it's 0.1xxxxx in binary, usually. IOW, the mantissa
> value is always in the range [0.5, 1).

> > Not 1000.xxx or 0.xxx, anyways--

> > if something like,

> > float x=1000;
> > float y=1000.43;
> > std::cout<< y-x<< std::endl;

> > will result in 0.429xxxx or whatever,

> It could.

> > why can calculator do it?

It can't, in general. Try something like 1.0/3.0.

> Because it probably uses more digits of precision than
> 'float'...

Or because it uses decimal arithmetic. Which is not only
slower (usually), but has the disadvantage of variable
precision.

If you're doing bookkeeping, or working in some other context
where the rounding rules are determined by a legal specification
based on decimal arithmetic, then you need a decimal class which
does decimal arithmetic. Typically, however, such applications
aren't "numbers crunchers", so you can afford the extra runtime.

> > Is there some other type that can be used to store precise
> > numbers of any size?

> Yes, look on the web for "arbitrary precision floating point
> library".

I'd be interested in seeing one capable of storing the exact
value of pi, or even the exact value of sqrt(2.0). Some numbers
require infinite precision in any base.

In practice, even simple division is a problem. You can only
store 1/n precisely in a finite number of bits if the base being
used is n or a multiple of n. In order to guarantee exactness,
you'd have to use some sort of rational representation.

Note that 10 is a multiple of 2, so with enough bits, you can
store any decimal representation. But this just begs the
question: numbers don't always come from literals or input
strings; they are also the result of expressions like a/b or
sqrt(c).

> Or you could use rationals (if your algorithm allows that).
> Or go for some kind of mathematical formula for the number.
> You're still going to be SOL with numbers like Pi or e (which
> aren't from a formula, really).

They can be expressed as the results of an equation.

> The built-in FP types are limited, there are only three. In
> addition to the two you've named there is the 'long double',
> which is allowed to be implemented as 'double'. Sucks, don'
> it?

Although neither made it into the final draft, there were
proposals on the table for decimal arithmetic and a rational
class. For that matter, I think the decimal arithmetic is being
adopted in the form of a technical report or something like
that.

--
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 5 ==
Date: Fri, Mar 27 2009 2:40 am
From: James Kanze


On Mar 26, 7:16 pm, "osmium" <r124c4u...@comcast.net> wrote:
> <carsonmy...@gmail.com> wrote:
> > so, I hear that the float and double intrinsic types don't
> > have very good precision, due to the way which they store
> > the data--they are meant to be stored as 1.xxxxx right? Not
> > 1000.xxx or 0.xxx, anyways-- if something like,

> > float x=1000;
> > float y=1000.43;
> > std::cout<< y-x<< std::endl;

> > will result in 0.429xxxx or whatever, why can calculator do
> > it? Is there some other type that can be used to store
> > precise numbers of any size?

> If calculators expressed numbers in binary form, they would
> have the general problem you allude to. I think they use a
> 4-bit group to represent a single decimal digit, and the
> exponent is similarly, represented as a separate, but
> associated, 2 decimal digit datum. IOW, it is not what a
> computer person would recognize as a floating point form.

It sounds like classical floating point to me. I don't know of
any modern machines which use decimal (although IBM mainframes
use base 16, and Unisys mainframes base 8), but they've
certainly existed in the past (e.g. IBM 1401). The C++ standard
references the C standard for this---see §5.2.4.2.2 in the C
standard.

> It is closer to what is called binary coded decimal but it is
> not that either.

It corresponds exactly to BCD: the number is broken down into
four bit blocks, each of which may take on a value of 0 to 9.

> But you can get a better idea of what I am talking about
> looking up BCD, on Wiki say. Using 4 bits to represent only
> 10 digits is wasteful, so be it.

On most machines, it is also slower. More importantly, it means
that the actual precision varies somewhat according to the
stored value; i.e. it has the same problems as IBM's base 16
format. (I'm not competent enough in numerical processing to
judge myself, but I know that some specialists complain loudly
about this.)

--
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 5 ==
Date: Fri, Mar 27 2009 4:16 am
From: Martin Eisenberg


James Kanze wrote:
>> carsonmyers@gmail.com wrote:

>> > if something like,
>> >
>> > float x=1000;
>> > float y=1000.43;
>> > std::cout<< y-x<< std::endl;
>> >
>> > will result in 0.429xxxx or whatever,
>> > why can calculator do it?

Actually they fudge it for your viewing pleasure by displaying
results rounded to less digits than they carry internally. To be
fair, there is a solid reason for that arrangement -- it stands a
reasonable chance to keep rounding errors, inevitably accumulating
over a chain of operations, out of the numbers that engineers end up
copying to their notebooks.

> In practice, even simple division is a problem. You can only
> store 1/n precisely in a finite number of bits if the base being
> used is n or a multiple of n. In order to guarantee exactness,
> you'd have to use some sort of rational representation.
>
> Note that 10 is a multiple of 2, so with enough bits, you can
> store any decimal representation.

You've used your own previous statement in the wrong direction.
Consider that 0.1 (dec) is periodic in binary.


Martin

--
Why is 6 afraid of 7?
Because 7 8 9.

==============================================================================
TOPIC: Does anyone else wish the C++ standards committee would give us parity
with other programming languages?
http://groups.google.com/group/comp.lang.c++/t/65479c8a9a474e0b?hl=en
==============================================================================

== 1 of 1 ==
Date: Fri, Mar 27 2009 12:19 am
From: Anonymous Infidel - Aborted Islam with a hanger


Or better yet, force them(C#, Java, etc) to do the catch up game....

==============================================================================
TOPIC: disadvantages of using STL
http://groups.google.com/group/comp.lang.c++/t/fb1f5fcc56ce965e?hl=en
==============================================================================

== 1 of 3 ==
Date: Fri, Mar 27 2009 12:27 am
From: coal@mailvault.com


>on Mar 27, 1:29 am, "Tony" <t...@my.net> wrote:
> "James Kanze" <james.ka...@gmail.com> wrote in message
>
> news:fae1e1aa-1d68-436c-be81-5a9abcee653f@g38g2000yqd.googlegroups.com...

>snipped<

Tony, I'd appreciate it if you would watch your language here.
O
> "Yes.  On the other hand, I've seen a couple of cases in my
> career where a software company or a consultant has
> (intentionally?) written code that no one else could understand,
> and then lived of over priced maintenance contracts for the rest
> of the programs lifetime.'
>
> Of course that is the goal of C++ gurus: to be god! "standard library": I'm
> not buying it. Language lock-in: I'm not buying it.

The STL is still decent. The Boost Intrusive library is
better than the STL in a number of ways and I expect it's
use will increase. I'm impressed recently by it's option
of a non constant-time size function. In the sort of code
I write, the use of size() is rare and not having to pay
for the field or increment/decrement it frequently makes
sense. Kudos to the Boost Intrusive library authors.

>
> (Aside to BS: You were wrong... you were an old senile man when you invented
> the language. ;) ).
>

I met Bjarne long after he invented the language and he
wasn't a senile man at that time. He was a friendly and
thoughtful host. Meanwhile, back at the ranch, gcc is
being developed in C as of March 27, 2009. That's where
we may find some senility. People who always do things
the same way are at greater risk of Alzheimer's than
those who change things up from time to time.


Brian Wood
Ebenezer Enterprises
www.webEbenezer.net


== 2 of 3 ==
Date: Fri, Mar 27 2009 12:37 am
From: coal@mailvault.com


On Mar 25, 3:52 am, James Kanze <james.ka...@gmail.com> wrote:
> On Mar 25, 6:48 am, c...@mailvault.com wrote:
>
> > It seems like there should be a term for that.
>
> There is.  At least in my book, it's called fraud if it's
> intentional, and incompetence otherwise.
>

Yes, it's a form of fraud. I would like a more colorful
term for it when it's not due to incompetence. "Code
Lawyer" would be a start. I'm thinking of the twister-
of-words aspect that describes a lot of lawyers.

Brian Wood
Ebenezer Enterprises
www.webEbenezer.net

== 3 of 3 ==
Date: Fri, Mar 27 2009 4:55 am
From: SG


On 27 Mrz., 07:41, "Tony" <t...@my.net> wrote:
> "Noah Roberts" <n...@nowhere.com> wrote in message
> > Anyone can obfuscate a design in their implementation.
> Cliches are like assholes.

Hello Tony,

it seems you don't have a lot to contribute to this (or any?)
discussion. I went through the trouble of reading all your posts in
this thread and the thread "C++ is complicated" again and the only
things that have stuck are:

* STL is supposedly complicated. It's more complicated
than your container library.
* You don't accept the STL being part of the C++ standard
library as an advantage even though obvious arguments
for this position have been mentioned.
* You prefer some "void*-based" container design (whatever
that means)
* You said that the STL's performance advantage "probably
doesn't matter".

This goes along with a lack of arguments and accusations à la
"Propaganda!", "You're a marketeer", "Bitch.", etc.

Nicely done, Tony.


-SG

==============================================================================
TOPIC: Using type prefixes with floating point constants
http://groups.google.com/group/comp.lang.c++/t/bb3e3831ff763cf0?hl=en
==============================================================================

== 1 of 1 ==
Date: Fri, Mar 27 2009 12:49 am
From: Bart van Ingen Schenau


On Mar 26, 2:54 pm, Ioannis Vranos <ivra...@freemail.spam.not.gr>
wrote:
> ISO/IEC 9899:1990/1995 says (from K&R2):
>
> "A6.4
>
> When a less precise floating value is converted to an equally or more
> precise floating type, the value is unchanged. When a more precise
> floating value is converted to a less precise floating type, and the
> value is within representable range, the result may be either the next
> higher or the next lower representable value. If the result is out of
> range, the behavior is undefined".
>
> Question: Does the above mean that it is a good practice or *always*
> needed to use the appropriate type suffixes with floating point constants?
>
I don't know about best practice---I don't use floating point often
enough for that---, but it certainly is not needed to always specify
the suffixes.

First of all, the majority of floating point constants are not exactly
representable in any of the floating point types, so you get the
conversion to the next higher or next lower representable value
anyway.
If float and double don't have the same range and precision, then a
compiler must be really perverse to get different results for the
expressions '(float)0.33439' and '0.33439F'.

The only suffix with more than documentary value is L (or l), if you
need the extra precision or range that long double might give you.

Bart v Ingen Schenau

==============================================================================
TOPIC: CRTP, member typedefs and access control
http://groups.google.com/group/comp.lang.c++/t/a3b80f88997409de?hl=en
==============================================================================

== 1 of 3 ==
Date: Fri, Mar 27 2009 1:09 am
From: Bart van Ingen Schenau


On Mar 26, 5:37 pm, "Hicham Mouline" <hic...@mouline.org> wrote:
> Hello,
>
> I have the following situation:
>
> template<typename Concrete>
> class Base {
>
> private:
>   typedef typename Concrete::Type1 t;
>
>  // use type t
>
> };
>
> class Derived : private Base<Derived> {
> private:
>   typedef double Type1;
>
> };
>
> Can this work? I get fairly complicated error messages with which I'm having
> a hard time deciphering,
> and I'm not sure Type1 is the cause.
> Do I need to declare friendship?

No, this can not work, and declaring friendship will not help either.

The problem is that in the definition of Base<>, you can not refer to
members of a derived class, because at the point where Base<Derived>
gets instantiated, Derived is not defined yet.
See also this thread:
http://groups.google.com/group/comp.lang.c++/browse_frm/thread/562d5a77cf4c1f12/ed886cdc72de4649

Bart v Ingen Schenau


== 2 of 3 ==
Date: Fri, Mar 27 2009 2:26 am
From: Lionel B


On Thu, 26 Mar 2009 14:03:06 -0400, Victor Bazarov wrote:

> Lionel B wrote:
>> On Thu, 26 Mar 2009 16:37:20 +0000, Hicham Mouline wrote:
>>
>>> Hello,
>>>
>>> I have the following situation:
>>>
>>> template<typename Concrete>
>>> class Base {
>>>
>>> private:
>>> typedef typename Concrete::Type1 t;
>>>
>>> // use type t
>>> };
>>>
>>> class Derived : private Base<Derived> { private:
>>> typedef double Type1;
>>> };
>>>
>>>
>>> Can this work?
>>
>> Can what work? What are you trying to achieve?
>>
>> This just looks weird to me... class Derived derives from a templated
>> base instantiated with *class Derived itself* as template parameter ?!?
>> Why? What can you do with this? Am I missing something?
>
> Read up on "CRTP" (it stands for "curiously recursive template
> pattern").

Cheers, have done. So, not weird... curious.

My thought on seeing the code was that this couldn't be useful since it
would not be possible to reference the derived class in the base
definition, since the derived class would at that point be incomplete (as
another poster suggests is in fact the case for the OP's code).

--
Lionel B


== 3 of 3 ==
Date: Fri, Mar 27 2009 2:53 am
From: "Hicham Mouline"

"Bart van Ingen Schenau" <Bart.van.Ingen.Schenau@ict.nl> wrote in message
news:dbfd1c58-b42b-4349-be52-d4a8213b7100@z1g2000yqn.googlegroups.com...
On Mar 26, 5:37 pm, "Hicham Mouline" <hic...@mouline.org> wrote:
> Hello,
>
> I have the following situation:
>
> template<typename Concrete>
> class Base {
>
> private:
> typedef typename Concrete::Type1 t;
>
> // use type t
>
> };
>
> class Derived : private Base<Derived> {
> private:
> typedef double Type1;
>
> };
>
> Can this work? I get fairly complicated error messages with which I'm
> having
> a hard time deciphering,
> and I'm not sure Type1 is the cause.
> Do I need to declare friendship?

>No, this can not work, and declaring friendship will not help either.

>The problem is that in the definition of Base<>, you can not refer to
>members of a derived class, because at the point where Base<Derived>
>gets instantiated, Derived is not defined yet.
>See also this thread:
>http://groups.google.com/group/comp.lang.c++/browse_frm/thread/562d5a77cf4c1f12/ed886cdc72de4649

>Bart v Ingen Schenau

Hi, after all,
I didn't need to derive the class from the base and have the CRTP. I moved
to containement,
where Based< Traits<Derived> > is now a private member of Derived.

Traits<Derived> contains whatever Base required to do its job,

rds,

==============================================================================
TOPIC: Techniques to reduce executable size
http://groups.google.com/group/comp.lang.c++/t/975f1b54c967ffef?hl=en
==============================================================================

== 1 of 1 ==
Date: Fri, Mar 27 2009 1:41 am
From: Bart van Ingen Schenau


On Mar 26, 10:39 pm, Paavo Helde <pa...@nospam.please.ee> wrote:
> "Qu0ll" <Qu0llSixF...@gmail.com> kirjutas:
>
> > I come from a Java world where we have tools like ProGuard which
> > analyze all the components of an application and strip out classes and
> > members that are not being used.  Is there an equivalent in C++ or
> > does this happen automatically?
>
<snip>

> The Java jar files are probably more similar to dynamic-link libraries, so

I would say that a jar file is comparable to the result of passing all
object files and libraries, that make up an application, to the
librarian instead of the linker.

For Java, that is an acceptable method of packaging, because every
machine that supports Java must be able to execute, interprer or
compile the byte-code.
For C++, there is no such assumption that the machine running the
application has the capability to link object files together. At best,
the machine is able to dynamically load parts of the application (when
it supports DLL/so's). For that reason, the packaging method of jar
files is not suitable for C++ code and there are no tools for C++ that
do something similar to ProGuard.

<sip>
> Another problem is that
> such stripping would depend on the application, so different applications
> would not be able to share the same dynamic library any more.

And one of the prime reasons for using DLL's is that different
applications are able to share the same library, so you can save disk
(only one copy of the library is needed) and memory space (multiple
running applications sharing the same library instance).
This would be completely negated if you have application-specific
stripped-down DLL versions.

For jar-files, this is not a concern, because their contents are not
shared between applications.

>
> hth
> Paavo

Bart v Ingen Schenau

==============================================================================
TOPIC: fstream - write a file
http://groups.google.com/group/comp.lang.c++/t/f149a5a9c1a12802?hl=en
==============================================================================

== 1 of 2 ==
Date: Fri, Mar 27 2009 1:48 am
From: James Kanze


On Mar 26, 10:50 am, Michael DOUBEZ <michael.dou...@free.fr> wrote:
> cplusplusquest...@gmail.com wrote:
> > In following code, the statement:
> > fd1 << "this is test";
> > can't write into a file. I don't know why.

> > #include <iostream>
> > #include <fstream>
> > #include <stdlib.h>
>
> > using namespace std;

> > void read(istream& fd){
> > string buffer;
> > getline(fd,buffer);

> > while(!fd.eof()) {

> if failbit or badbit is raised before that, you will have an
> infinite loop.

And using getline, he'll probably not read the last line.

> Prefer:
> while(fd)
> {
> > getline(fd, buffer);

And of course, this can fail (but since he never used the
results, it doesn't matter).

> > }
> > }

I'll admit that I don't understand the reason behind this
function too well. You read an entire file into a local
variable, one line at a time, each line overwriting the other,
but you never do anything with the data you've read.

A simple seek to the end of file would do the same thing, more
or less. (I forget when getline does if the file doesn't end
with a '\n'.)

> > int main(int argc, char **argv) {
> > if (argc < 2){
> > cout << "arg less than 2\n";
> > exit(1);
> > }

> > ifstream fd(argv[1], ios::in | ios::out);

> From your code, you may be interested in adding ios::app which
> set the stream's position to the end before each output and
> ios::ate which does the same on opening the file

Since he never writes to the stream, I'm not sure what the
ios::out is doing in there. I can't think of any reason, off
hand, to add ios::out to an ifstream. (Maybe to ensure that an
empty file is created, if there is no file of that name? If so,
it's pretty subtle, but no more so, I guess, than adding ios::in
to an ofstream to prevent truncating the file.)

> > if (!fd){
> > cerr << "cannot open first file" << argv[1] << endl;
> > exit(1);
> > }

> > while (!fd.eof()){
> > read(fd);

> failbit may be raised outputs won't occur. try to clear it.
> fd.clear();

This is more or less the same loop as is in read. I will never
be executed more than once.

> > fstream fd1(argv[2], ios::in | ios::out);

> You don't write in fd1. Maybe an ifstream would be more
> appropriate.

And again, there's no need of ios::out. Except that he does
write to fd1, after having read the entire file.

> Moreover, you don't need to specify
> ios::in|ios::out each time, this is the default value.

> > if (!fd1){
> > cerr << "cannot open second" << argv[2] << endl;
> > exit(1);
> > }

> > while (!fd1.eof()){
> > read(fd1);
> > fd1 << "this is test";

This is a tricky issue. Since he's read to end of file, eofbit
and failbit will have been set. Which means that all further
operations are no-ops, until they've been cleared.

In practice: each time you read, you should verify the status
after the read, to know if it succeeded. And each time you
change orientations, you should clear any previously detected
errors. (There's also a rule in C, which probably applies to
C++ as well, that input should not immediately follow output
without an intervening flush.)

> > }
> > fd1.close();

If you've written anything, you should definitely test the
status of the stream after the close(). (If he'd have done
this, he'd have noticed that the stream was in error.

> > }

> > fd.close();
> > return 0;
> > }

--
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 2 ==
Date: Fri, Mar 27 2009 2:46 am
From: Michael DOUBEZ


James Kanze wrote:
> On Mar 26, 10:50 am, Michael DOUBEZ <michael.dou...@free.fr> wrote:
>> cplusplusquest...@gmail.com wrote:
>>> In following code, the statement:
>>> fd1 << "this is test";
>>> can't write into a file. I don't know why.
>
>>> #include <iostream>
>>> #include <fstream>
>>> #include <stdlib.h>
>>> using namespace std;
>
>>> void read(istream& fd){
>>> string buffer;
>>> getline(fd,buffer);
>
>>> while(!fd.eof()) {
>
>> if failbit or badbit is raised before that, you will have an
>> infinite loop.
>
> And using getline, he'll probably not read the last line.
>
>> Prefer:
>> while(fd)
>> {
>>> getline(fd, buffer);
>
> And of course, this can fail (but since he never used the
> results, it doesn't matter).
>
>>> }
>>> }
>
> I'll admit that I don't understand the reason behind this
> function too well. You read an entire file into a local
> variable, one line at a time, each line overwriting the other,
> but you never do anything with the data you've read.
>
> A simple seek to the end of file would do the same thing, more
> or less. (I forget when getline does if the file doesn't end
> with a '\n'.)

From 21.3.7.9/6
6 Effects: [...] extracts characters from is and appends them to str as
if by calling str.append(1,c) until any of the following occurs:
— end-of-file occurs on the input sequence (in which case, the getline
function calls is.setstate(ios_base::eofbit)).
— c == delim for the next available input character c (in which case, c
is extracted but not appended) (27.4.4.3)
— str.max_size() characters are stored (in which case, the function
calls is.setstate(ios_base::failbit) (27.4.4.3)
7 The conditions are tested in the order shown. In any case, after the
last character is extracted, the sentry object k is destroyed.
8 If the function extracts no characters, it calls
is.setstate(ios_base::failbit) which may throw ios_base::failure (27.4.4.3).

I would say that if the file does end with a '\n', no character are
extracted and article 8 applies (failbit is raised) which I find counter
intuitive.

--
Michael

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

== 1 of 1 ==
Date: Fri, Mar 27 2009 2:03 am
From: James Kanze


On Mar 26, 8:44 pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:

[...]
> >> Those are good suggestions, and we all can agree that to
> >> optimize one most often needs to measure first. But it
> >> does not take a measurement to know that IO is a
> >> bottleneck. In every application. Hardware is
> > I partially disagree.

> With what, exactly?

> > IO is always slow, that's true.

> That's it. Period. Slow. When you read data from a file or
> write data to a file, IO is the bottleneck, not conversions
> (if any), not compression (if any), not creation of any other
> auxiliary objects...

That's usually true, but not always. I've seen cases where
compression was a "bottleneck" (although this is relative---in
the final code, more time was spent on compression than on the
physical writes, but the program was still faster with the
compression, since it wrote a lot less). And I've seen cases
where where allocations were far more significant than the
actual writes. So there are exceptions.

And of course, if you're writing to a pipe under Unix, the
writes can be very, very fast.

> > But for many applications the time spent doing and waiting
> > for IO is not the majority of their run time.

> No, but what does their overall run time have to do with the
> fact that during reading or writing data the interaction with
> the device through the platform abstractions (isn't that what
> the streams are?) is the slowest part?

Well, if you eliminate the other causes, IO will end up being
the slowest remaining part.

> Why do customers care about startup time or the time it takes
> to load a file into the application? They only do it a few
> times a day.

That depends on the application. I've written servers that run
for years at a time---startup time isn't significant. But I've
also written a lot of Unix filters, which are invoked
interactively (often on a block of text in the editor). In such
cases, start-up time can be an issue. (If you doubt it, try
using one written in Java---where loading the classes ensures a
significantly long start up time.)

> And if the application is stable, you don't have to shut it
> down at all, ever, right?

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; you don't want
start up time to be too long there, either. (Note that on the
server I currently work on, the start-up time is several tens of
seconds---the time to reconstruct all of the persistent data
structures in memory, resynchronize with the data base, etc.)

--
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: Corrected: Using type suffixes with floating point constants
http://groups.google.com/group/comp.lang.c++/t/e4b6beec5748ef9f?hl=en
==============================================================================

== 1 of 1 ==
Date: Fri, Mar 27 2009 2:12 am
From: James Kanze


On Mar 26, 11:30 pm, Victor Bazarov <v.Abaza...@comAcast.net> wrote:

[...]
> No, the above does not mean that. You need to look at the
> definition of the FP literals. The suffix only says what type
> the literal has. The suffix does not control potential
> precision. IOW

> float Pi = 3.1415926;
> float Pi_ = 3.1415926f;

> will *likely* have the same value since the number of digits
> (8) in the literals is greater than 'float' can represent (7),
> and both numbers will be "fixed", only at different times, so
> to speak.

First, as you know, a float can have more than 8 decimal digits
of precision. I'll suppose that we're talking about the usual
IEEE float here.

> The former will be squeezed into a 'float' at the time of
> initialising of 'Pi' (formally by your program), the other
> will be squeezed into a 'float' by the compiler upon creating
> the literal. It is conceivable that the numbers will be
> different *if* your compiler uses a different way of "fixing"
> of the value to fit into a 'float' than your program (which
> can actually be controlled in some cases by a flag in the
> CPU/FPU, IIRC).

The big difference is that formally, the first involves two
roundings: decimal to double, then double to float. This
certainly could, in certain cases, result in a difference in the
LSB.

--
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: operator overloading simple question
http://groups.google.com/group/comp.lang.c++/t/f176f1743eb21cb4?hl=en
==============================================================================

== 1 of 3 ==
Date: Fri, Mar 27 2009 2:49 am
From: Sam Hu


Dir Sirs,

This is just a question from a C++ newbie regarding the operator
overloading.Since I do not want to use friend key word,I write class
graduate as below:

//graduate.h
#ifndef GRADUATE_H
#define GRADUATE_H

#include <iostream>
#include <string>

using namespace std;

class graduate
{
public:
/** Default constructor */
graduate();
string getDegree() const;
bool isEqual(const graduate& rhs);
bool lessThan(const graduate& rhs);

istream& getfrom(istream& istr)const;
ostream& sendto(ostream& ostr)const;

protected:
private:
string name;
string degree;
};
bool operator==(const graduate& lhs,graduate& rhs)
{
return lhs.isEqual(rhs);
}
bool operator<(const graduate& lhs,graduate& rhs)
{
return lhs.lessThan(rhs);

}
istream& operator>>(istream& istr,const graduate& grad)const
{
return grad.getfrom(istr);
}
ostream& operator<<(ostream& ostr,const graduate& grad)const
{
return grad.sendto(ostr);
}
graduate::graduate()
{
//ctor
}
/** @brief getDegree
*
* @todo: document this function
*/
string graduate::getDegree() const
{
return degree;
}

/** @brief getfrom
*
* @todo: document this function
*/
istream & graduate::getfrom(istream& istr)const
{
char ch;
istr>>this.name;
istr>>ch;
istr>>this.degree;
return istr;


}

/** @brief isEqual
*
* @todo: document this function
*/
bool graduate::isEqual(const graduate& rhs)
{
return this.name==rhs.name;
}

/** @brief sendto
*
* @todo: document this function
*/
ostream & graduate::sendto(ostream& ostr)const
{
ostr<<"Name:"<< this.name<<"\tdegree:"<<this.degree<<endl;
return ostr;
}
/** @brief lessThan
*
* @todo: document this function
*/
bool graduate::lessThan(const graduate& rhs)
{
return this.name<rhs.name;

}

No comments: