 |
 |
|
 |
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
This is the frankly laughable title of the book I'm currently borrowing.
Sure, maybe you could learn BBC BASIC in 21 days. But C++? I doubt it.
The lesson plan looks... interesting. Take a look:
Day #1: Compiling, linking and running.
Day #2: Program structure. Functions.
Day #3: Variables and constants. Assignments. Printing results.
Day #4: Statements, blocks and expressions. Branching.
Day #5: Writing functions.
Day #6: Writing classes and creating objects. Constructors.
Day #7: For loops. While loops. If/then/else. Switch/case.
Day #8: Pointers.
Day #9: References.
Day #10: Overloading. Dynamic allocation.
Day #11: Inheritance. Virtual member functions.
Day #12: Arrays. Strings. Pointer arithmetic.
Day #13: Multiple inheritance. Abstract classes. Pure virtual functions.
Day #14: Static members. Static functions. Pointers to functions.
Day #15: Containment and delegation.
Day #16: Streams. File I/O.
Day #17: Namespaces.
Day #18: OO analysis and design.
Day #19: Templates. STL.
Day #20: Exception handling.
Day #21: Conditional compilation. The C preprocessor.
Riiiight. So, let's see, on day #6 you start writing and using classes -
a fairly advanced topic. And the next day, you learn /how to write a
for-loop/, which is bread-and-butter stuff that every programmer knows
about. That's... interesting.
Oh, look. Day #12, you learn about inheritance, and the next day you
learn about /arrays/?
I'm also loving the complete lack of any coherent direction or
organisation. It's like somebody decided what topics need to be in the
book, and then did a random shuffle on them. One minute you're learning
about arrays and strings, and the next minute it's multiple inheritance.
Wuh??
Suffice it to say, I'm not expecting much from this book. But who knows,
maybe it will surprise me? Anyway, I've been working from an online
resource, but it really doesn't go into enough detail. (E.g., it doesn't
explain what a copy constructor is [or even mention that they exist],
and that seems kinda important to me.) So now I'm going to try this book.
The /other/ fun thing is that the book claims to be compliant with the
"final ANSI/ISO C++ standard". Yeah, well, it was published in 1999. I'm
going to go out on a limb and say the C++ standard may have changed
slightly since then. ;-)
If I find any particularly amusing remarks, I'll let you know...
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Em 14/04/2012 12:23, Orchid Win7 v1 escreveu:
> This is the frankly laughable title of the book I'm currently borrowing.
>
> Sure, maybe you could learn BBC BASIC in 21 days. But C++? I doubt it.
>
> The lesson plan looks... interesting. Take a look:
>
> Day #1: Compiling, linking and running.
> Day #2: Program structure. Functions.
> Day #3: Variables and constants. Assignments. Printing results.
> Day #4: Statements, blocks and expressions. Branching.
> Day #5: Writing functions.
> Day #6: Writing classes and creating objects. Constructors.
> Day #7: For loops. While loops. If/then/else. Switch/case.
> Day #8: Pointers.
> Day #9: References.
> Day #10: Overloading. Dynamic allocation.
> Day #11: Inheritance. Virtual member functions.
> Day #12: Arrays. Strings. Pointer arithmetic.
> Day #13: Multiple inheritance. Abstract classes. Pure virtual functions.
> Day #14: Static members. Static functions. Pointers to functions.
> Day #15: Containment and delegation.
> Day #16: Streams. File I/O.
> Day #17: Namespaces.
> Day #18: OO analysis and design.
> Day #19: Templates. STL.
> Day #20: Exception handling.
> Day #21: Conditional compilation. The C preprocessor.
>
> Riiiight. So, let's see, on day #6 you start writing and using classes -
> a fairly advanced topic. And the next day, you learn /how to write a
> for-loop/, which is bread-and-butter stuff that every programmer knows
> about. That's... interesting.
>
> Oh, look. Day #12, you learn about inheritance, and the next day you
> learn about /arrays/?
>
> I'm also loving the complete lack of any coherent direction or
> organisation. It's like somebody decided what topics need to be in the
> book, and then did a random shuffle on them. One minute you're learning
> about arrays and strings, and the next minute it's multiple inheritance.
> Wuh??
>
> Suffice it to say, I'm not expecting much from this book. But who knows,
> maybe it will surprise me? Anyway, I've been working from an online
> resource, but it really doesn't go into enough detail. (E.g., it doesn't
> explain what a copy constructor is [or even mention that they exist],
> and that seems kinda important to me.) So now I'm going to try this book.
>
> The /other/ fun thing is that the book claims to be compliant with the
> "final ANSI/ISO C++ standard". Yeah, well, it was published in 1999. I'm
> going to go out on a limb and say the C++ standard may have changed
> slightly since then. ;-)
>
> If I find any particularly amusing remarks, I'll let you know...
you have wasted precious minutes writing these that I'm sure you won't
recover from you alloted minutes on the topic about makefiles...
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Orchid Win7 v1 <voi### [at] dev null> wrote:
> Sure, maybe you could learn BBC BASIC in 21 days. But C++? I doubt it.
It depends on the depth of your C++ understanding that you want to
achieve.
Certainly things like dynamic allocation, pointers (including their
triple role as pointers to individual values, pointers to arrays, and
iterators, not to talk about function and method pointers), pointer
arithmetic, const correctness, the so-called "rule of three" (which with
the new C++ is actually the "rule of five"), RAII, stack vs. heap
allocation, templates, the standard library and its usage, as well as
all the things you have to know in order to avoid shooting yourself in
the foot will take significantly more than 21 days to master.
This is not even going as far as including more advanced low-level
stuff such as virtual inheritance, placement-new, bitfields and
template metaprogramming.
OTOH, you can learn to make simple (and safe, although not necessarily
efficient) programs in that time, with the proper teacher.
> Riiiight. So, let's see, on day #6 you start writing and using classes -
> a fairly advanced topic.
Not really. Classes are the most basic element of OO programming (and
also the most intuitive part), so IMO they should be taught on the *first*
day. (This does not include inheritance and dynamic binding, though. That
can wait.)
> Oh, look. Day #12, you learn about inheritance, and the next day you
> learn about /arrays/?
Inheritance is much less useful than people thought 20 years ago
(it still has its uses in *some* situations, but much less than predicted).
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Le 2012-04-14 11:23, Orchid Win7 v1 a écrit :
> The /other/ fun thing is that the book claims to be compliant with the
> "final ANSI/ISO C++ standard". Yeah, well, it was published in 1999. I'm
> going to go out on a limb and say the C++ standard may have changed
> slightly since then. ;-)
>
Which edition of the book do you have? The first one came out in 1996,
before the actual standard.
--
/*Francois Labreque*/#local a=x+y;#local b=x+a;#local c=a+b;#macro P(F//
/* flabreque */L)polygon{5,F,F+z,L+z,L,F pigment{rgb 9}}#end union
/* @ */{P(0,a)P(a,b)P(b,c)P(2*a,2*b)P(2*b,b+c)P(b+c,<2,3>)
/* gmail.com */}camera{orthographic location<6,1.25,-6>look_at a }
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Le 14/04/2012 17:23, Orchid Win7 v1 nous fit lire :
>
> Sure, maybe you could learn BBC BASIC in 21 days. But C++? I doubt it.
It's a bit like "Learn to handle a hammer in 21 days".
It might teach a lot of technical details (hammer a nail in wood, in
plaster, how to nail two pieces at 90°... ), yet I'm afraid it will not
provide the global vision and design needed for a good carpenter.
(OO design, rationales about approaches)
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 15/04/2012 04:21 AM, Francois Labreque wrote:
> Le 2012-04-14 11:23, Orchid Win7 v1 a écrit :
>> The /other/ fun thing is that the book claims to be compliant with the
>> "final ANSI/ISO C++ standard". Yeah, well, it was published in 1999. I'm
>> going to go out on a limb and say the C++ standard may have changed
>> slightly since then. ;-)
>>
>
> Which edition of the book do you have? The first one came out in 1996,
> before the actual standard.
I have the 3rd edition, published 1999. (The standard was, what, 1998?)
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 15/04/2012 09:58 AM, Le_Forgeron wrote:
> Le 14/04/2012 17:23, Orchid Win7 v1 nous fit lire :
>>
>> Sure, maybe you could learn BBC BASIC in 21 days. But C++? I doubt it.
>
> It's a bit like "Learn to handle a hammer in 21 days".
>
> It might teach a lot of technical details (hammer a nail in wood, in
> plaster, how to nail two pieces at 90°... ), yet I'm afraid it will not
> provide the global vision and design needed for a good carpenter.
>
> (OO design, rationales about approaches)
We all know there's only /one/ way to learn C++ in 21 days. ;-)
Post a reply to this message
Attachments:
Download '21days.png' (66 KB)
Preview of image '21days.png'

|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Em 15/04/2012 07:00, Orchid Win7 v1 escreveu:
> On 15/04/2012 09:58 AM, Le_Forgeron wrote:
>> Le 14/04/2012 17:23, Orchid Win7 v1 nous fit lire :
>>>
>>> Sure, maybe you could learn BBC BASIC in 21 days. But C++? I doubt it.
>>
>> It's a bit like "Learn to handle a hammer in 21 days".
>>
>> It might teach a lot of technical details (hammer a nail in wood, in
>> plaster, how to nail two pieces at 90°... ), yet I'm afraid it will not
>> provide the global vision and design needed for a good carpenter.
>>
>> (OO design, rationales about approaches)
>
> We all know there's only /one/ way to learn C++ in 21 days. ;-)
not the only, just the easiest. :)
yeah, developing an age-reversing formula and a flux-capacitor is easier
than teaching yourself C++ is 21 days... :)
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 4/14/2012 10:41, Warp wrote:
> Inheritance is much less useful than people thought 20 years ago
Software ICs! Never rewrite code!
I remember doing one fairly hairy (at the time) bit of coding for some
graphics line clipping thing in Smalltalk, and thinking to myself "well,
I'll never have to write *that* again." :-)
--
Darren New, San Diego CA, USA (PST)
"Oh no! We're out of code juice!"
"Don't panic. There's beans and filters
in the cabinet."
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 14/04/2012 06:41 PM, Warp wrote:
> Orchid Win7 v1<voi### [at] dev null> wrote:
>> Sure, maybe you could learn BBC BASIC in 21 days. But C++? I doubt it.
>
> It depends on the depth of your C++ understanding that you want to
> achieve.
> OTOH, you can learn to make simple (and safe, although not necessarily
> efficient) programs in that time, with the proper teacher.
Well, maybe. My initial impressions of this book are not great.
>> Riiiight. So, let's see, on day #6 you start writing and using classes -
>> a fairly advanced topic.
>
> Not really. Classes are the most basic element of OO programming (and
> also the most intuitive part), so IMO they should be taught on the *first*
> day. (This does not include inheritance and dynamic binding, though. That
> can wait.)
I guess it depends. You can start at the top, explaining OO theory and
then working down to how you write code with it. Or you can start with
writing simple procedural code, working up to using functions, and then
using classes and other OO features. Either way would be logical. The
way this book seems to do everything is to just jumble it all up in
fairly random order.
> Inheritance is much less useful than people thought 20 years ago
> (it still has its uses in *some* situations, but much less than predicted).
My university lecturer asserted that "inheritance is overused, and
collaboration is underused".
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> Day #1: Compiling, linking and running.
> Day #2: Program structure. Functions.
> Day #3: Variables and constants. Assignments. Printing results.
> Day #4: Statements, blocks and expressions. Branching.
> Day #5: Writing functions.
Well, I wasn't expecting great things. And I'm not /finding/ great
things. :-P
Day 1 contains almost no code. Which is fair enough. It begins by
explaining how all complex programs inherently have to be written using
OO techniques or they will be too difficult. It continues by explaining
how somebody took C, the best programming language in the world, and
added OO features to it to create C++, the new best programming language
in the world.
On one point it is clear: Should I learn C before learning C++? The
answer comes back as "no". Which seems quite correct to me.
On the subject of Java, it made me laugh. (Remember when this is
published: 1999.) Apparently "all the C++ programmers who left for Java
are now coming back to C++". That made me chuckle. As if C++ and Java
target the same problem domain or something. But the real giggler was this:
"In any case, C++ and Java are so similar that learning one involves
learning 90% of the other."
If that doesn't make you laugh out loud, I don't know what will. ;-)
Then we are told that "more than any other programming language, C++
demands that you /design/ a program before you build it". Followed by
some mumbo-jumbo about how programmer time is more expensive than
machine time, and how design mistakes are expensive, etc.
Half way through, we get to type in Hello World and run it. As you'd expect.
Then there's a cryptic reference to the fact that iostream and
iostream.h aren't the same, but the differences are "subtle, exotic, and
beyond the scope of an introductory primer". Yes, the 879-page monolith
of a book is only an "introductory primer".
(Incidentally, the table of contents runs to 21 pages. I always feel
that if the table of contents /itself/ merits another table of contents,
you're doing it wrong.)
Anyway, the book decides that it's going to stick with iostream.h,
possibly for compatibility reasons - it isn't really elaborated on much.
The chapter closes out with "You should feel confident that learning C++
is the right decision for anyone interested in programming in the next
decade."
Because, let's face it, C++ is the only programming language in use,
isn't it?
(Some comment about "interested in programming" verses "interested in
getting paid to program" could perhaps be made here...)
Day 2 continues to supply the laughs, opening with such gems as
"Every time you run the compiler, the preprocessor runs. The
preprocessor is discussed on day 21."
Right. So you've just brought up the fact that this thing called a
preprocessor exists, and in the next breath told me you're not going to
actually explain that at all until /the final chapter of the book/?
The entire book is riddled with stuff like this. Basically sentences
saying "you won't understand this for another two weeks". Yeah, great,
thanks for that. Mind you, if the order wasn't quite so scrambled up, it
would be easier. And I'm fairly sure you don't need an entire "day" just
to comprehend Hello World. (Does somebody have pages to fill?)
Anyway, apparently main() must always return int. It is against the ANSI
standard for it to return void. (No mention of it having parameters.
Indeed, even the return value is described as an "obscure feature which
we won't make use of".)
In keeping with the above, we are told that the notation "\n" won't be
explained until day 17 (although actually it's explained on day 3, in
complete contradiction to this statement), that cout is an object and we
won't find out what the heck that means until day 6, and cout is also a
stream and that isn't explained until day 16. (Why are you bothering to
tell me about all the things you aren't going to tell me about? Can't
you /summarise/ the salient points quickly or something?)
Then there's some mumbo-jumbo about how you can use cout "to do
addition", and how when you do count << 8+5, then "8+5 is passed to
cout, but 13 is what is actually printed". Nice, clear explanation,
that. :-P
There's a little bit about comments and how they work. The author
suggests that "comments should not explain /what/ is happening, but
/why/ it is happening".
And then the book insists that we have to learn about functions,
"because they're used constantly". So we learn how to define new
functions, how to call them, how to pass arguments into them and return
values out of them. Notice that we haven't learned about what variables
are or how to use them yet. We also haven't learned about types yet. But
the book insists that functions come first. It then goes on to not
define any function except main() for the next several chapters. :-P
In an example demonstrating all this, cin is casually dropped in but not
mentioned anywhere. Presumably we're supposed to /guess/ this detail.
"The difficulty of programming is that so much of what you have to learn
depends on everything else." Pfft. I think you just suck at explaining
it. :-P
Day 3: ...and /now/ we get to learn what variables are, how to assign to
them, and what types there are and how to use them. Because, hey, we
couldn't possibly have done that /before/ learning about passing
arguments to functions, no?
There's some garbled mumbo about how "memory" and "RAM" are different.
It doesn't really make sense.
And then it starts talking about types. Apparently C++ adds a new "bool"
type, which is supposed to be 1 byte. Apparently "char" doesn't mean
character at all, it means a 1-byte integer (and by default, a signed one).
Now, this I did not know, but: There is a long int, and a short int. And
then there's just int. I had always thought these were three different
sizes of integer. But it appears that actually, long int is one size,
short int is another size, and plain int refers to whichever one the
compiler writer chose on a whim. So there's only actually two integer
sizes, and plain int means "I don't care".
The book helpfully points out that on a "Pentium" system, int = long
int, whereas on older PCs int = short int. (Remember when this was
published? 1999?)
The book suggests "never use int, always use short int or long int". If
the table is to be believed, long int is 32-bits. Christ knows what you
do if you want more bits than that...
But hey, at least double and float work in a sane way, right?
The book casually mentions something which /seems/ to be claiming that
variables are not initialised to anything in particular unless you
specifically request this. That's interesting; I didn't know that.
We are shown how to do a typedef. And then we get a nice little program
to print out (the printable parts of) the ASCII character set. (Notice
that we haven't covered for-loops yet, and the program consists of a
single for-loop.)
On page 50, I get a chuckle when next to an example listing, they feel
the need to point out that "*" denotes multiplication. Even though we've
already used it to perform multiplication in a dozen examples so far.
Hmm, might wanna put that earlier in the book if you feel it's
necessary. :-P
It tells you how to use enum. Looks simple enough.
Apparently assigning a double to an int is only a /warning/, not a
compile-time error. The book helpfully fails to specify how the
conversion is actually done. (From the examples, it appears to round
towards negative infinity... but it would be kinda useful to have that
/stated/.)
Alright, Day 4! And the first thing we learn is this: Every C++
statement is also an expression.
This is obviously an extremely sick and twisted idea, and whoever
thought of it was either mentally disturbed or merely failed to
comprehend what a horrifying thing he just did.
On one hand, it means that
x = y = z;
is a perfectly valid statement in C++. On the other hand, it also means that
while (x[i] = y[i--]) ;
is perfectly valid. You sick, sick people.
Apparently every R-value is an L-value, but not vice versa. Which is
fair enough, I guess.
In most programming languages, performing division promotes integers to
reals. But not in C++, apparently. (Again, it is unspecified exactly how
integer division works. Whether the author actually doesn't /know/ how
it works or merely thought it unimportant is unclear.) At this point, we
are told that there's two ways to convert something to an double:
double x = (double)y;
double x = static_cast<double>y;
Apparently the former is bad, and the latter is good. No indication as
to why, it just is.
More giggles: There's a list of the self-modification operators. Check
it out:
+= Self-addition.
= Self-subtraction.
*= Self-multiplication.
/= Self-division.
Notice something missing there?
Then we get the ++ and -- operators explained to us. (Even though we've
already seen them used several times.) This being C++, some insane wacko
thought that having c++ and ++c would be a good idea, and wouldn't be
confusing in any way.
Next we learn that false=0, and true /= 0. (Christ, I'm /never/ going to
remember that!) Apparently there's a new bool type, but details are thin
as to what the exact significance of this is.
Then we learn about if/then, if/then/else, and finally ?: is
demonstrated, without once mentioning how it's different from
if/then/else. (I.e., it only works on expressions, not statements. Oh,
but wait! Silly me, statements /are/ expressions...)
Day 5 begins by explaining, all over again, what functions are, why
that's useful, and how you use them. We learn how to pass values in, and
return results out. So... /why/ did we need this in day 2, in half as
much detail and then never used again?
Apparently every function must be declared before it can be used. (This
constantly trips me up...) It seems a function prototype doesn't need to
include argument names, just their types. (If only Java was like this!)
Bizarrely, if you don't specify a return type, it defaults to int. Not,
say, void. :-o
We've got a source code listing where one line of text is randomly
indented by a different amount than the rest of the surrounding code.
Clearly this book has been through some tough QA. I'm only 92 pages into
it - that's about 10% of the way through.
There's a side-box that shows you the syntax for a function prototype
[even though the text already explained this]. But, for reasons unknown,
the diagram /actually/ shows a normal function definition, but with a
stray semicolon at the end of the prototype... In short, somebody seems
to have got their stuff mixed up.
It appears that in C++ it is legal for a function to overwrite its
arguments. In fact, there's an example of implementing a swap()
function, to demonstrate that it completely fails to swap its arguments
in the caller. Having done an extensive demonstration to call our
attention to this fact, we learn that we won't be told how to write
swap() correctly until day 8. Thanks for that. Couldn't you have brought
this example up, say, on day 8?
It seems that C++ allows variables to be declared anywhere inside a
block, and that variable is then local to the inner-most block. (Not
that the text says it this clearly.) And it appears that nested
functions are not allowed. Which is fine.
Then we learn about global variables. Apparently if you write a variable
outside of any block, it's global. No word on exactly when it's
initialised, or precisely what "global" actually means. For example, I'm
/guessing/ the variable is only in-scope /below/ the line where it's
defined. That's how functions work, after all.
The book then warns about the dangers of using global variables. To
quote the book itself:
"In C++, global variables are legal, but they are almost never used.
C++ grew out of C, and in C global variables are a dangerous but
necessary tool."
"Globals are dangerous because they are shared data, and one function
can change a global variable in a way that is invisible to another
function. This can and does create bugs that are very difficult to find."
"On Day 14 you'll see a powerful alternative to global variables that
C++ offers, but that is unavailable in C."
So now you understand why global variables are bad, right?
No, I didn't think so.
As somebody who first learned to program in BASIC, where /all/ variables
are global variables, I know all about how unsafe global variables are.
But this book makes no real attempt to explain what the problem is,
other than that "a function could change a global variable in a way that
is invisible to another function". WTF is /that/ supposed to even /mean/?!
Seriously. It's /slightly important/ to understand why using a global
variable is a bad idea. This is basic bread-and-butter programming
knowledge. Way to completely fail to explain it. :-P
Next, we learn that function arguments can have default values. But get
this:
"Any or all of the function's parameters can be assigned default
values. The one restriction is this: If any of the parameters does not
have a default value, no previous parameter may have a default value."
...um, what?
So you're saying that you can freely choose which ones have defaults,
except that if a parameter doesn't have a default, nothing to the left
can either?
So, aren't you basically saying all of the non-default parameters have
to come before all of the default parameters? That doesn't sound like
"any or all of the function's parameters can be assigned default
values". That sounds like the parameters are split into two chunks. Why
not just /say/ that? :-P
We are now on page 108, and that's where I stopped reading. So far none
of the burning questions I want answered have been addressed. But the
next chapter looks promising. I just hope it doesn't try to explain that
metaphore about an object being like a spark plug again... >_<
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Le 16/04/2012 22:11, Orchid Win7 v1 nous fit lire :
>> Day #1: Compiling, linking and running.
>> Day #2: Program structure. Functions.
>> Day #3: Variables and constants. Assignments. Printing results.
>> Day #4: Statements, blocks and expressions. Branching.
>> Day #5: Writing functions.
>
> Well, I wasn't expecting great things. And I'm not /finding/ great
> things. :-P
>
>
>
> Day 1 contains almost no code. Which is fair enough. It begins by
> explaining how all complex programs inherently have to be written using
> OO techniques or they will be too difficult. It continues by explaining
> how somebody took C, the best programming language in the world, and
> added OO features to it to create C++, the new best programming language
> in the world.
>
> On one point it is clear: Should I learn C before learning C++? The
> answer comes back as "no". Which seems quite correct to me.
Well, there is nothing really to learn in C, once you have learned
assembly programming of course.
>
> On the subject of Java, it made me laugh.
> "In any case, C++ and Java are so similar that learning one involves
> learning 90% of the other."
Right & wrong. Class, reference, direct inheritance are similar. complex
inheritance, exception handling, pointer are not.
Traditional Java C++ war... not interesting.
> Then we are told that "more than any other programming language, C++
> demands that you /design/ a program before you build it". Followed by
> some mumbo-jumbo about how programmer time is more expensive than
> machine time, and how design mistakes are expensive, etc.
Well, they should look at some Ada or smalltalk... but it's right. Think
before you start coding.
> Then there's a cryptic reference to the fact that iostream and
> iostream.h aren't the same, but the differences are "subtle, exotic, and
> beyond the scope of an introductory primer". Yes, the 879-page monolith
> of a book is only an "introductory primer".
I.e: the author has no clue for you.
>
> Day 2 continues to supply the laughs, opening with such gems as
>
> Anyway, apparently main() must always return int. It is against the ANSI
> standard for it to return void.
The problem is to explain Unix: the return of main() is used as the
return of the called program... and some utility like "make" use that
result to check success or failure.
> Then there's some mumbo-jumbo about how you can use cout "to do
> addition", and how when you do count << 8+5, then "8+5 is passed to
> cout, but 13 is what is actually printed". Nice, clear explanation,
> that. :-P
Oh great, it's not cout that does the addition any way! So you now have
a false explanation.
>
> There's a little bit about comments and how they work. The author
> suggests that "comments should not explain /what/ is happening, but
> /why/ it is happening".
At least a sensible sentence.
What is happening, at low level, is in the code.
Why it is happening is of higher level, and should be put in the comment.
> In an example demonstrating all this, cin is casually dropped in but not
> mentioned anywhere. Presumably we're supposed to /guess/ this detail.
Guess what: it's an input stream (whereas cout is output stream)
> Day 3:
> And then it starts talking about types. Apparently C++ adds a new "bool"
> type, which is supposed to be 1 byte. Apparently "char" doesn't mean
> character at all, it means a 1-byte integer (and by default, a signed one).
The definition of type are inherited from C (and they f****d it large).
There was no bool in C.
A char is enough bits to store a native glyph. and you can assume that
the number of bit is at least 8.
It can be 9. It can be 16. It can even be 32. (the 9 are met only on
architecture with 9 bits per bytes in the hardware bus)
One warning: sizeof() will return the size in char, not bytes.
Second warning: the signedness of char is local to the compiler.
>
> Now, this I did not know, but: There is a long int, and a short int. And
> then there's just int. I had always thought these were three different
> sizes of integer. But it appears that actually, long int is one size,
> short int is another size, and plain int refers to whichever one the
> compiler writer chose on a whim. So there's only actually two integer
> sizes, and plain int means "I don't care".
In 1999, there was only issue with 3 integers type. It was 32 bits time.
On nowadays 64 bits, there is also a new one "long long int" !
As inherited from C, it's a total garbage, you can only assume:
char <= short <= int <= long <= long long
unsigned char can store up to 255
unsigned short can store up to 65535
unsigned long can store up to 2^32-1
unsigned long long can store up to 2^64-1
Notice that it is possible that "char = long"
>
> The book suggests "never use int, always use short int or long int". If
> the table is to be believed, long int is 32-bits. Christ knows what you
> do if you want more bits than that...
>
> But hey, at least double and float work in a sane way, right?
Do not rely on that. I'm not sure C mandate that the double & float
should obey the IEEE-754 rules, or even their size, nor their
representation and mantissa/offset bitcount.
Usually, float is a 32 bits, double is 64 bits. But it is known that
some compiler would perform the computation on 80 bits registers...
>
> The book casually mentions something which /seems/ to be claiming that
> variables are not initialised to anything in particular unless you
> specifically request this. That's interesting; I didn't know that.
Yep, variables are allocated, but whatever was in the memory at that
time is their value. You'd better set one.
> Apparently assigning a double to an int is only a /warning/, not a
> compile-time error. The book helpfully fails to specify how the
> conversion is actually done. (From the examples, it appears to round
> towards negative infinity... but it would be kinda useful to have that
> /stated/.)
The problem is they did not yet introduce the promotion/implicit cast.
Issue: it might be a local architecture/compiler choice.
> Alright, Day 4! And the first thing we learn is this: Every C++
> statement is also an expression.
>
> This is obviously an extremely sick and twisted idea, and whoever
> thought of it was either mentally disturbed or merely failed to
> comprehend what a horrifying thing he just did.
>
> On one hand, it means that
>
> x = y = z;
>
> is a perfectly valid statement in C++. On the other hand, it also means
> that
>
> while (x[i] = y[i--]) ;
>
> is perfectly valid. You sick, sick people.
It came from C. Put the blame on C.
>
> Apparently every R-value is an L-value, but not vice versa. Which is
> fair enough, I guess.
>
> In most programming languages, performing division promotes integers to
> reals. But not in C++, apparently. (Again, it is unspecified exactly how
> integer division works. Whether the author actually doesn't /know/ how
> it works or merely thought it unimportant is unclear.)
Operation on integers are perform with integers.
Integer division is performed as usual: 14/5 is 2.
> At this point, we
> are told that there's two ways to convert something to an double:
>
> double x = (double)y;
>
> double x = static_cast<double>y;
>
> Apparently the former is bad, and the latter is good. No indication as
> to why, it just is.
cast is bad. Cast with () is bad.
Cast with static_cast<> is bad also, but at least you know it.
(it's bad by design: if you need a double, pass a double)
I'm in favor of calling the constructor instead... but you have not seen
that yet.
double x(y);
> This being C++, some insane wacko
> thought that having c++ and ++c would be a good idea, and wouldn't be
> confusing in any way.
They are just explaining C so far.
>
> Next we learn that false=0, and true /= 0. (Christ, I'm /never/ going to
> remember that!) Apparently there's a new bool type, but details are thin
> as to what the exact significance of this is.
Once again, C did not had bool, C++ has.
>
> Then we learn about if/then, if/then/else, and finally ?: is
> demonstrated, without once mentioning how it's different from
> if/then/else. (I.e., it only works on expressions, not statements. Oh,
> but wait! Silly me, statements /are/ expressions...)
not really. expression becomes statement when you push a ; at the end.
And now for a mad trick: if you follow an expression with a , (comma),
its value will be replaced by the expression after the comma...
you only need one statement per block. so you can do dirty mad function
like:
int foo()
{
return bar(),zoo()?kel():azbe(),foobar();
}
And it works in assignment & tests too...
>
>
>
> Day 5 begins by explaining, all over again, what functions are, why
> that's useful, and how you use them. We learn how to pass values in, and
> return results out. So... /why/ did we need this in day 2, in half as
> much detail and then never used again?
>
> Apparently every function must be declared before it can be used. (This
> constantly trips me up...) It seems a function prototype doesn't need to
> include argument names, just their types. (If only Java was like this!)
> Bizarrely, if you don't specify a return type, it defaults to int. Not,
> say, void. :-o
yep. C++ is maniac: you must provide the prototype before using the
function.
You can have the parameter's names in the prototype if you like.
> There's a side-box that shows you the syntax for a function prototype
> [even though the text already explained this]. But, for reasons unknown,
> the diagram /actually/ shows a normal function definition, but with a
> stray semicolon at the end of the prototype... In short, somebody seems
> to have got their stuff mixed up.
Nop.
int main(int,char**); // is enough for the compiler
int main(int argc, char** argv); // is more similar to the definition
Both are ok.
>
> It appears that in C++ it is legal for a function to overwrite its
> arguments. In fact, there's an example of implementing a swap()
> function, to demonstrate that it completely fails to swap its arguments
> in the caller. Having done an extensive demonstration to call our
> attention to this fact, we learn that we won't be told how to write
> swap() correctly until day 8. Thanks for that. Couldn't you have brought
> this example up, say, on day 8?
>
> It seems that C++ allows variables to be declared anywhere inside a
> block, and that variable is then local to the inner-most block. (Not
> that the text says it this clearly.) And it appears that nested
> functions are not allowed. Which is fine.
Variable can be declared anywhere. including in a for() parentheses.
They are usable from their declaration down to the end of the
inner-block that contained them.
(in the case of the for(), they can be used inside the () and the {}
block of the for, but not further)
>
> Then we learn about global variables. Apparently if you write a variable
> outside of any block, it's global. No word on exactly when it's
> initialised, or precisely what "global" actually means. For example, I'm
> /guessing/ the variable is only in-scope /below/ the line where it's
> defined. That's how functions work, after all.
Global variables are either scoped by the file in which they are (static
prefix), or to the whole program.
(you haven't seen namespace yet).
Their position is irrelevant, but it's like prototype and declaration:
you need the prototype before using it. The declaration of a global
variable can also be used as its prototype, but you can only have one
declaration.
prototype (at head or in a header file):
int foo;
declaration (anywhere, usually at head to avoid a prototype):
int foo=5;
> So now you understand why global variables are bad, right?
>
> No, I didn't think so.
> Seriously. It's /slightly important/ to understand why using a global
> variable is a bad idea. This is basic bread-and-butter programming
> knowledge. Way to completely fail to explain it. :-P
>
> Next, we learn that function arguments can have default values. But get
> this:
>
> "Any or all of the function's parameters can be assigned default
> values. The one restriction is this: If any of the parameters does not
> have a default value, no previous parameter may have a default value."
>
> ...um, what?
In foo(a,b,c,d,e), if you do not provide a default value for c, you
cannot provide one for either a or b.
At one point in the argument list, you must start providing default
values, for all argument at the right of that point.
>
> So you're saying that you can freely choose which ones have defaults,
> except that if a parameter doesn't have a default, nothing to the left
> can either?
Yes.
>
> So, aren't you basically saying all of the non-default parameters have
> to come before all of the default parameters? That doesn't sound like
> "any or all of the function's parameters can be assigned default
> values". That sounds like the parameters are split into two chunks. Why
> not just /say/ that? :-P
Because, in usage, with the strong typing of C++, you might nevertheless
provide some arguments and get the default values for others.
foo(a,b,d) might be possible (with a prototype of foo(a,b,c=,d=,e=); )
as long as the type of d is not related to the one of c (but it's more
complex, due to internal type promotion by the parser)
(you should understand "foo(a,b,c,d,e)" as "foo(type_a a, type_b b,
type_c c, type_d d, type_e e)", and so on for the default)
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> On one point it is clear: Should I learn C before learning C++? The
>> answer comes back as "no". Which seems quite correct to me.
>
> Well, there is nothing really to learn in C, once you have learned
> assembly programming of course.
Except that assembly generally follows a simple and consistent syntax,
whereas C is written in C. :-P
>> On the subject of Java, it made me laugh.
>
>> "In any case, C++ and Java are so similar that learning one involves
>> learning 90% of the other."
>
> Right& wrong. Class, reference, direct inheritance are similar. complex
> inheritance, exception handling, pointer are not.
>
> Traditional Java C++ war... not interesting.
War nothing. The two languages bear a superficial resemblance to each
other, but beyond that they're /radically different/. To the degree that
learning any OO language helps you learn any other OO language, C++ and
Java are similar. Beyond that, they're two totally different languages.
Learning Java teaches you maybe 10% of C++, not 90%. And vice versa.
>> Then we are told that "more than any other programming language, C++
>> demands that you /design/ a program before you build it".
>
> Well, they should look at some Ada or smalltalk... but it's right. Think
> before you start coding.
Try Haskell. A typical coding session involves coming up with a
breakthrough mathematical insight, followed by some ingenious
programming. Certainly you can't just hack on it until it works.
> I.e: the author has no clue for you.
Yeah, that's pretty much the conclusion I reached too.
It says in the preface that the author is the president of some company
that supplies C++ training. It doesn't say anywhere that he's actually a
C++ programmer. :-P
>> Anyway, apparently main() must always return int. It is against the ANSI
>> standard for it to return void.
>
> The problem is to explain Unix: the return of main() is used as the
> return of the called program... and some utility like "make" use that
> result to check success or failure.
Not just make; a whole host of programs make use of a program's return
code. (And not just on Unix either; Windows does the same.) But this is
apparently an "obscure feature" which you don't need to know about. :-P
>> Then there's some mumbo-jumbo about how you can use cout "to do
>> addition", and how when you do count<< 8+5, then "8+5 is passed to
>> cout, but 13 is what is actually printed". Nice, clear explanation,
>> that. :-P
>
> Oh great, it's not cout that does the addition any way! So you now have
> a false explanation.
With this level of conceptual muddling about something of fundamental
importance, you can see why my opinion of the book is so low. :-P
>> "comments should not explain /what/ is happening, but
>> /why/ it is happening".
>
> At least a sensible sentence.
Yeah. The purpose of comments is to explain stuff which /isn't/ obvious
from reading the source code itself. (I'm also of the opinion that less
is more. I dislike code that's so littered with comments that you can't
see the code properly. Then again, maybe that's because I don't have a
syntax highlighter...)
>> In an example demonstrating all this, cin is casually dropped in but not
>> mentioned anywhere. Presumably we're supposed to /guess/ this detail.
>
> Guess what: it's an input stream (whereas cout is output stream)
Oh, *I* know that. But no thanks to the book that's supposed to be
teaching me. :-P
> The definition of type are inherited from C (and they f****d it large).
> There was no bool in C.
> A char is enough bits to store a native glyph. and you can assume that
> the number of bit is at least 8.
> It can be 9. It can be 16. It can even be 32. (the 9 are met only on
> architecture with 9 bits per bytes in the hardware bus)
That's pretty messed up.
> One warning: sizeof() will return the size in char, not bytes.
Oh, that's fun. Let us hope that char *is* one byte, otherwise... damn!
I guess this is why autoconf exists. :-P
> Second warning: the signedness of char is local to the compiler.
Really? The book seems to say that all integer types default to signed,
unless you request unsigned. (AFAIK, there isn't a way to request signed.)
> In 1999, there was only issue with 3 integers type. It was 32 bits time.
Well, the book still talks about 16-bit code.
> On nowadays 64 bits, there is also a new one "long long int" !
long long int? Woah, that's special...
> As inherited from C, it's a total garbage, you can only assume:
>
> char<= short<= int<= long<= long long
> Notice that it is possible that "char = long"
So much for C and C++ being for system-level programming. :-P
>> But hey, at least double and float work in a sane way, right?
>
> Do not rely on that. I'm not sure C mandate that the double& float
> should obey the IEEE-754 rules, or even their size, nor their
> representation and mantissa/offset bitcount.
Well, no, it'll be whatever the underlying platform supports. Which on
any sane x86 system is going to be IEEE-754. If I was trying to program
a microcontroller, I might be worried. On a desktop PC, I'm not too
concerned.
> Usually, float is a 32 bits, double is 64 bits. But it is known that
> some compiler would perform the computation on 80 bits registers...
Is there a way to explicitly request 80 bits?
> Yep, variables are allocated, but whatever was in the memory at that
> time is their value. You'd better set one.
Right. So if I request a 2GB array, it won't actually sit there trying
to zero all 2GB of RAM, right before my for-loop rolls over it to
initialise it /again/.
>> Apparently assigning a double to an int is only a /warning/, not a
>> compile-time error. The book helpfully fails to specify how the
>> conversion is actually done.
>
> Issue: it might be a local architecture/compiler choice.
Oh God.
>> while (x[i] = y[i--]) ;
>>
>> is perfectly valid. You sick, sick people.
>
> It came from C. Put the blame on C.
C, the PDP assembly language that thinks it's a high-level language. :-P
(I forgot who wrote that...)
>> In most programming languages, performing division promotes integers to
>> reals. But not in C++, apparently. (Again, it is unspecified exactly how
>> integer division works. Whether the author actually doesn't /know/ how
>> it works or merely thought it unimportant is unclear.)
>
> Operation on integers are perform with integers.
> Integer division is performed as usual: 14/5 is 2.
So, it always rounds downwards?
>> Next we learn that false=0, and true /= 0. (Christ, I'm /never/ going to
>> remember that!) Apparently there's a new bool type, but details are thin
>> as to what the exact significance of this is.
>
> Once again, C did not had bool, C++ has.
I notice that "true" and "false" seem to be valid names now, which is
useful...
> And now for a mad trick: if you follow an expression with a , (comma),
> its value will be replaced by the expression after the comma...
Oh that's sick. So comma really /is/ an operator? Wow, that's evil.
I wonder if brackets are operators too? Perhaps you can do some crazy
code obfuscation with that as well. :-P
>> Apparently every function must be declared before it can be used. (This
>> constantly trips me up...) It seems a function prototype doesn't need to
>> include argument names, just their types. (If only Java was like this!)
>> Bizarrely, if you don't specify a return type, it defaults to int. Not,
>> say, void. :-o
>
> yep. C++ is maniac: you must provide the prototype before using the
> function.
> You can have the parameter's names in the prototype if you like.
I was referring more to the fact that it's legal to not specify the
return type, and if you don't, it defaults to something absurd.
>> There's a side-box that shows you the syntax for a function prototype
>> [even though the text already explained this]. But, for reasons unknown,
>> the diagram /actually/ shows a normal function definition, but with a
>> stray semicolon at the end of the prototype... In short, somebody seems
>> to have got their stuff mixed up.
>
> Nop.
>
> int main(int,char**); // is enough for the compiler
> int main(int argc, char** argv); // is more similar to the definition
>
> Both are ok.
To be clear: The diagram claims that a "function prototype" looks like this:
double foo(int, int, int) ;
{
statement1;
statement2;
statement3;
}
This is neither a valid prototype nor a valid definition. It's garbage.
If you take out the function body, it becomes a valid prototype. If you
take out the semicolon and add some argument names, it becomes a valid
definition. But is written, it's garbage.
>> Then we learn about global variables. Apparently if you write a variable
>> outside of any block, it's global. No word on exactly when it's
>> initialised, or precisely what "global" actually means. For example, I'm
>> /guessing/ the variable is only in-scope /below/ the line where it's
>> defined. That's how functions work, after all.
>
> Global variables are either scoped by the file in which they are (static
> prefix), or to the whole program.
> (you haven't seen namespace yet).
> Their position is irrelevant, but it's like prototype and declaration:
> you need the prototype before using it. The declaration of a global
> variable can also be used as its prototype, but you can only have one
> declaration.
>
> prototype (at head or in a header file):
> int foo;
>
> declaration (anywhere, usually at head to avoid a prototype):
> int foo=5;
You just explained more in a handful of sentences than the book
explained in an entire chapter. :-P
>> Next, we learn that function arguments can have default values. But get
>> this:
>>
>> "Any or all of the function's parameters can be assigned default
>> values. The one restriction is this: If any of the parameters does not
>> have a default value, no previous parameter may have a default value."
>>
>> ...um, what?
>
> At one point in the argument list, you must start providing default
> values, for all argument at the right of that point.
...which makes infinitely more sense than what the book said. :-P
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Perhaps more alarming than anything I read in a book: Apparently in C++
it is legal for a function to not have a return statement.
As in, I declared my function as returning a value. I ran the program
and printed out the result of the function. I got a segfault. I changed
the code a bit, and ran it again. This time, it printed garbage, and
/then/ it segfaulted.
When I looked at my function, I found I'd written "it->second;" rather
than "return it->second;". Not only is this apparently legal, it doesn't
even generate a compile-time /warning/.
(Contrast this with Java. If the compiler cannot statically prove that
every single possible program branch ends with a return or a throw, it
point-blank refuses to compile your class. It gives you warnings if code
is unreachable. It even complains if you have a void function that uses
return just to exit early, and there's nothing afterwards...)
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 16/04/2012 09:11 PM, Orchid Win7 v1 wrote:
> Day 5
>
> We are now on page 108, and that's where I stopped reading.
OK. So the book bothers to go to all the trouble of explaining what an
inline function is, and why that's good. And in the next sentence, it says:
"Note that inline functions can bring a heavy cost. If the function
is called 10 times, the inline code is copied into the calling functions
each of those 10 times. The tiny improvement in speed you might achieve
is more than swamped by the increase in the size of the executable
program. Even the speed increase might be illusory. First, today's
optimizing compilers do a terrific job on their own, and declaring a
function inline almost never results in a big gain. More important, the
increased size brings its own performance cost."
In other words "now that we've explained how to use this feature, you
should never, ever use it". Great. Thanks for that...
Now, I'm used to programming languages where the decision to inline
something or not is down to the compiler. It's not something an
application programmer would ever have to worry about. And it seems that
the inline directive is only a "hint" in C++ anyway, so I have to
wonder, whether this particular directive is now obsolete.
The book has this to say on the subject of recursion:
"Both types of recursion, direct and indirect, come in two varieties:
those that eventually end and produce an answer, and those that never
end and produce a runtime failure. Programmers think that the latter is
quite funny (when it happens to somebody else)."
Um... WTF?
Anyway, this is followed by an O(n^2) time Fibonacci function. I kid you
not. Because, let's face it, obscure mathematical problems with no
connection to reality are the only reason anybody would ever use
recursion, right? :-D
I love the dire warnings that you could use a number less than 15,
because otherwise the program might consume a vast amount of memory.
(For goodness' sake, how much RAM does 15 stack frames take up?!)
"Some compilers have difficulty with the use of operators in a cout
statement. If you receive a warning on line 28, place parentheses around
the subtraction operation."
I'm going to go out on a limb and guess that this stopped being a
problem ten years ago. :-P
Anyway, like the previous segment, we wrap up with
"Recursion is not used often in C++ programming, but it can be a
powerful and elegant tool for certain needs. Recursion is a tricky part
of advanced programming. It is presented here because it can be useful
to understand the fundamentals of how it works, but don't worry too much
if you don't fully understand all the details."
In other words, yet again, "now you know how this works, you don't need
to actually use it".
Now we get a tale about how function calling works.
"Most introductory books don't try to answer these questions, but
without understanding this information, you'll find that programming
remains a fuzzy mystery."
Uh... yeah, whatever.
"Few programmers bother with any level of detail below the idea of
values in RAM. [...] You do need to understand how memory is organized,
however. Without a reasonably strong mental picture of where your
variables are when they are created and how values are passed among
functions, it will all remain an unmanageable mystery."
I'm not sure what's so "unmanageable" about it all. Provided you don't
try to reach behind the abstraction, there's no particular need to
understand how it works. Then again, this is a low-level language, and
if you're bothering to code in it, that probably means that you're
intending to go behind the abstractions at some point...
"As a C++ programmer, you'll often be concerned with the global name
space, the free store, the registers, the code space, and the stack."
OK.
"Registers are a special area of memory built right into the CPU."
Erm...
"They take care of internal housekeeping."
...actually...
"A lot of what goes on in the registers is beyond the scope of this
book, but what we are concerned with is the set of registers responsible
for pointing, at any given moment, to the next line of code. We'll call
these registers, together, the instruction pointer."
So I'm guessing an architecture exists where the instruction pointer
/isn't/ a single register then? :-P
I'm loving how they have to explain the idea of a stack using a crude
drawing of a smiling, happy man putting a plate onto the top of a stack
of plates. Because saying that in a sentence just doesn't bring it home,
does it?
I'm looking at the description of function calls now. I'm loving how in
step #3, the base address of the function is loaded into the instruction
pointer, and then in step #5 the function's arguments are pushed onto
the stack. Are you /sure/ it happens in that order??
Still, it does answer something I've always wondered about: What *is*
the C calling convention? Apparently it's to pass all function arguments
and function results via the stack, and also to store all local
variables on the stack. (By contrast, if you're coding in assembly,
usually you pass everything in registers. Apparently C doesn't do this.)
Ho hum. On to day 6, where hopefully I'm going to start learning
something useful...
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 17/04/2012 11:16, Invisible wrote:
> Perhaps more alarming than anything I read in a book: Apparently in C++
> it is legal for a function to not have a return statement.
>
> As in, I declared my function as returning a value. I ran the program
> and printed out the result of the function. I got a segfault. I changed
> the code a bit, and ran it again. This time, it printed garbage, and
> /then/ it segfaulted.
>
> When I looked at my function, I found I'd written "it->second;" rather
> than "return it->second;". Not only is this apparently legal, it doesn't
> even generate a compile-time /warning/.
It's when I read things like that that I'm glad I found C# :-)
Post a reply to this message
|
 |
|  |
|  |
|
 |
From: Invisible
Subject: Re: Teach yourself C++ in 21 strange malfunctions
Date: 17 Apr 2012 06:55:49
Message: <4f8d4c35@news.povray.org>
|
|
 |
|  |
|  |
|
 |
>> When I looked at my function, I found I'd written "it->second;" rather
>> than "return it->second;". Not only is this apparently legal, it doesn't
>> even generate a compile-time /warning/.
>
> It's when I read things like that that I'm glad I found C# :-)
It's when I see things like this that I'm glad I use Haskell, not some
low-level performance-oriented language that doesn't mind giving you
garbage results if it makes the code 0.02% faster...
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> It's when I read things like that that I'm glad I found C# :-)
>
> It's when I see things like this that I'm glad I use Haskell, not some
> low-level performance-oriented language that doesn't mind giving you
> garbage results if it makes the code 0.02% faster...
...and then I feel depressed because I'm the only person in the UK who
programs in Haskell, and the rest of the industry /does/ use C++,
regardless of what I think about it. :-(
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Le 17/04/2012 12:47, Invisible a écrit :
>
> Still, it does answer something I've always wondered about: What *is*
> the C calling convention? Apparently it's to pass all function arguments
> and function results via the stack, and also to store all local
> variables on the stack. (By contrast, if you're coding in assembly,
> usually you pass everything in registers. Apparently C doesn't do this.)
C cannot assume a single processor, hence cannot have a set of registers
for arguments.
(on a M68000, what would you do if your functions has more than 16
arguments (D0-D7 and A0-A7) ? And on that small i286, more than 4 16 bits ?)
Not only does everything goes on the stack, but the alignment on the
stack is also sensible to the compiler (and the ABI mode).
(and in C, there is sometimes a difference in the stacking of arguments
when K&R or ANSI prototype has been provided (or not, in which case K&R
is assumed); C++ does not have that issue, as prototype is mandatory)
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
"You make a new type by declaring a class."
Wrong.
"A class is just a collection of variables - often of different types -
combined with a set of related functions."
It might be more accurate to say that an /object/ is a collection of
variables. At any rate, "collection" usually means something more
specific in this case.
"A class enables you to encapsulate, or bundle, these variables parts
and various functions into one collection, which is called an object."
Where do I start?
I'm pretty sure "encapsulate" doesn't mean what you think it means. :-P
A "collection" usually refers to a group of objects, which isn't what
you're talking about.
And finally, this is perhaps the most vague definition of an object I've
ever heard. :-P
The next goes on to explain that classes are good because everything
related to a thing is in one place. (Like you couldn't just write all
the code together if it wasn't for classes.) Obviously this /isn't/
what's so special about classes. The /actual/ benefits don't appear to
be mentioned.
I'm going to stop now, because otherwise I'll just go on forever... >_<
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> It's when I see things like this that I'm glad I use Haskell, not some
> low-level performance-oriented language that doesn't mind giving you
> garbage results if it makes the code 0.02% faster...
Has Haskell ever been used for something where the execution speed is
actually important? :-)
If Haskell had a decent IDE and easy documented access to the rest of
the system I might consider using it. But then F# exists already and I
haven't paid much attention to that so far...
I think you need to be working with very specific types of problems to
warrant using Haskell, which isn't to say nobody uses it.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Orchid Win7 v1 <voi### [at] dev null> wrote:
> Then there's a cryptic reference to the fact that iostream and
> iostream.h aren't the same, but the differences are "subtle, exotic, and
> beyond the scope of an introductory primer".
One is standard, the other isn't. What is there more to explain?
> (Incidentally, the table of contents runs to 21 pages. I always feel
> that if the table of contents /itself/ merits another table of contents,
> you're doing it wrong.)
I have sometimes seen the opposite extreme: A doorstopper book with
a laughably small table of contents which isn't very helpful.
> Anyway, apparently main() must always return int. It is against the ANSI
> standard for it to return void. (No mention of it having parameters.
> Indeed, even the return value is described as an "obscure feature which
> we won't make use of".)
I don't think it would have been very hard to say something like "the
return value is used by the operating system as a success/failure value"
and then explain that 0 means success and other values can be used as a
failure code. (It is actually important to know this especially when
creating a command-line program. The return value of main() is
significant.)
> Then there's some mumbo-jumbo about how you can use cout "to do
> addition", and how when you do count << 8+5, then "8+5 is passed to
> cout, but 13 is what is actually printed". Nice, clear explanation,
> that. :-P
Actually "8+5" is not being passed to cout. cout is getting one single
integral value. (Basically invariably this value will be calculated by
the compiler at compile time.) Anyways, it's not like it's important.
> And then it starts talking about types. Apparently C++ adds a new "bool"
> type, which is supposed to be 1 byte.
I don't think the standard defines the size of bool. Most compilers
probably make it 1.
> Apparently "char" doesn't mean
> character at all, it means a 1-byte integer (and by default, a signed one).
The standard only guarantees that sizeof(char) is 1, but not that char
is 1 byte. (It is possible for char to be larger in some systems. It just
means that everything else is then a multiple of that size.)
The standard also lets the signedness of char as implementation-defined.
(In most practical systems it's signed.)
(Curiously, "char" and "signed char" are two *different* types in C and
C++ even if "char" is signed, while for example "int" and "signed int" are
completely synonymous and the "signed" keyword is redundant in the latter
case. This comes from the prehistoric dark ages of C.)
> Now, this I did not know, but: There is a long int, and a short int. And
> then there's just int. I had always thought these were three different
> sizes of integer. But it appears that actually, long int is one size,
> short int is another size, and plain int refers to whichever one the
> compiler writer chose on a whim. So there's only actually two integer
> sizes, and plain int means "I don't care".
Nope. The standard does not say that. The only thing the standard says
is that:
sizeof(char) <= sizeof(short) <= sizeof(int) <= sizeof(long)
and that sizeof(char) = 1 (which does not mean "1 byte", but "1 indexable
memory unit".)
(Yes, it is possible and standard-conforming for char to be as large
as long.)
In practice in most 32-bit systems short will be 16 bits and int/long
will be 32 bits. In most 64-bit systems it will be the same except that
long will be 64 bits.
Curiously, the new standard specifically states that the new "long long"
type has to be at least 64 bits. (The new standard also defines official
typedefs for integrals of specific sizes.)
> The book suggests "never use int, always use short int or long int". If
> the table is to be believed, long int is 32-bits. Christ knows what you
> do if you want more bits than that...
"Never use int" is a silly thing to say.
If you need an integral that's the natural word size of the target system,
use int. If you need an integral with a specific number of bits, use one
of the new standard typedefs. Use "long long" for an integral of at least
64 bits (at least if your compiler supports C++11). There's no standard
support for larger integrals (because they are not supported by CPUs).
> The book casually mentions something which /seems/ to be claiming that
> variables are not initialised to anything in particular unless you
> specifically request this. That's interesting; I didn't know that.
C hackers don't want the extra clock cycle to initialize a variable
which will be immediately assigned a new value anyways.
As a side effect you get all kinds of weird behavior if you forget to
initialize a variable.
> Apparently assigning a double to an int is only a /warning/, not a
> compile-time error. The book helpfully fails to specify how the
> conversion is actually done.
The integral part of the value is assigned to the int.
> is a perfectly valid statement in C++. On the other hand, it also means that
> while (x[i] = y[i--]) ;
> is perfectly valid. You sick, sick people.
I think that's Undefined Behavior because the same variable is being
modified and referenced more than once in the same expression.
Even if it isn't UB, better not do it like that.
> In most programming languages, performing division promotes integers to
> reals. But not in C++, apparently.
C is a wrapper around assembly, and assembly supports integral division.
Hence dividing integers performs integral division. Oftentimes you *want*
integral division (in which case promoting to floating point would be an
enormous waste of resources).
If you really want promotion to floating point, then you have to cast
explicitly.
> At this point, we
> are told that there's two ways to convert something to an double:
> double x = (double)y;
> double x = static_cast<double>y;
> Apparently the former is bad, and the latter is good. No indication as
> to why, it just is.
The former casts *anything* into a double, while the latter casts only
compatible types. (Which means that the latter will give you a compiler
error if you try to cast from an incompatible type by mistake.)
> This being C++, some insane wacko
> thought that having c++ and ++c would be a good idea, and wouldn't be
> confusing in any way.
Who gets confused? I don't.
There's certainly a big difference between eg:
while(c++ < 10) std::cout << c << "\n";
and
while(++c < 10) std::cout << c << "\n";
If you don't want to made the increment "inline" like that, the
alternative is more verbose.
> Next we learn that false=0, and true /= 0. (Christ, I'm /never/ going to
> remember that!) Apparently there's a new bool type, but details are thin
> as to what the exact significance of this is.
You are never going to remember that 0 is false?
> Then we learn about if/then, if/then/else, and finally ?: is
> demonstrated, without once mentioning how it's different from
> if/then/else. (I.e., it only works on expressions, not statements. Oh,
> but wait! Silly me, statements /are/ expressions...)
?: cannot contain blocks of code, and both branches much evaluate to
the same type. No such limitation for if/then/else.
> Bizarrely, if you don't specify a return type, it defaults to int. Not,
> say, void. :-o
Not in standard C++ (where it's an error).
> Then we learn about global variables. Apparently if you write a variable
> outside of any block, it's global. No word on exactly when it's
> initialised, or precisely what "global" actually means. For example, I'm
> /guessing/ the variable is only in-scope /below/ the line where it's
> defined. That's how functions work, after all.
If you define a variable (or function) in the global namespace, it will
be visible in the entire program. (Yes, you can access it from a different
compilation unit. You just need to declare it with "extern" in that other
compilation unit to do that.)
The problem with global variables is, obviously, name clashes. You'll
start getting weird linker errors about duplicate names if you make a habit
of using lots of globals (and then happen to use the same name in two
compilation units).
(Also, from a design point of view, global variables decrease abstraction,
which is bad.)
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 17/04/2012 01:44 PM, scott wrote:
>> It's when I see things like this that I'm glad I use Haskell, not some
>> low-level performance-oriented language that doesn't mind giving you
>> garbage results if it makes the code 0.02% faster...
>
> Has Haskell ever been used for something where the execution speed is
> actually important? :-)
Well... The Haskell compiler itself. The Darcs source control system.
Several web frameworks / web servers. (If you believe the hype, some of
these web servers rival Apache in terms of performance.)
If there's one thing Haskell lacks, it's a "killer application". There's
nothing I can really point at which demonstrates either the speed or
usefulness of Haskell. The best I can do is some microbenchmarks on the
language shootout.
> If Haskell had a decent IDE and easy documented access to the rest of
> the system I might consider using it. But then F# exists already and I
> haven't paid much attention to that so far...
Haskell has /an/ IDE... I'm not sure it warrants the description of
"decent" yet though. Last time I tried it, it had reached the stage of
"kinda clunky, but basically usable".
http://antimatroid.files.wordpress.com/2010/07/leksah.png
If by "easy access to the rest of the system" you mean "it works great
on POSIX systems", then yeah, sure. :-) Oh, wait, you meant Windows, the
platform that 98% of the entire world uses? Sorry, no luck.
(OK, that's a slight exaggeration. The basic system works flawlessly on
all popular platforms. But if you want to talk to the outside world, you
end up needing to know very low level system calls.)
If you want /documentation/... then yeah, I see why you're not using
Haskell.
In short, in terms of how nicely it's all packaged up, Haskell just
can't compete with the might of Java or F# or Erlang or whatever.
Haskell is a hobby project put together by a few dozen open-source
developers from around the world. It's got nothing on Microsoft or
Oracle or Ericsson.
> I think you need to be working with very specific types of problems to
> warrant using Haskell, which isn't to say nobody uses it.
What, you mean like programs involving complex data manipulations?
Problems where you want to actually get the correct answer? Problems
where you'd like to be able to still understand the code in two years'
time? Because, to me, that sounds like a pretty /huge/ problem domain. ;-)
It's sad, really. You can use C or Java or whatever, which is horrible
to code in but lets you actually get stuff done. Or you can code in
Haskell, which is a joyful celebration of how programming should be, but
then it's a nightmare to actually interact with the outside world... I
keep hoping that some day this situation will be fixed. But I doubt it.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Invisible <voi### [at] dev null> wrote:
> "Note that inline functions can bring a heavy cost. If the function
> is called 10 times, the inline code is copied into the calling functions
> each of those 10 times. The tiny improvement in speed you might achieve
> is more than swamped by the increase in the size of the executable
> program.
He seems to think that the 'inline' keyword forces the compiler to inline.
It doesn't. The compiler is completely free to not inline it, if it decides
that it would be detrimental.
As for increasing the size of the executable, who cares? If the executable
gets a few hundreds of bytes larger, big deal.
The 'inline' keyword has a secondary, but much more important role,
though: It's an instruction for the compiler that says, basically, "if
this function appears in more than one compilation unit, don't give me
a linker error; instead merge them into one".
Anyways, 'inline' should usually only be used for very short functions
that are absolutely crucial for speed. Otherwise there's little benefit.
> Now, I'm used to programming languages where the decision to inline
> something or not is down to the compiler. It's not something an
> application programmer would ever have to worry about. And it seems that
> the inline directive is only a "hint" in C++ anyway, so I have to
> wonder, whether this particular directive is now obsolete.
Some newer compilers (such as the newest version of gcc) are able to
inline functions between compilation units. However, this is a rare,
quite advanced feature. (AFAIK only gcc implements this so far.)
Traditionally, if you need a short function to be as fast as possible,
you need to define it in the module's header file, and then it *must* be
declared 'inline' (or else you'll get linker errors).
> I love the dire warnings that you could use a number less than 15,
> because otherwise the program might consume a vast amount of memory.
> (For goodness' sake, how much RAM does 15 stack frames take up?!)
That would probably be 15^2. The author might have been using a 16-bit
DOS compiler.
> "Recursion is not used often in C++ programming, but it can be a
> powerful and elegant tool for certain needs. Recursion is a tricky part
> of advanced programming. It is presented here because it can be useful
> to understand the fundamentals of how it works, but don't worry too much
> if you don't fully understand all the details."
> In other words, yet again, "now you know how this works, you don't need
> to actually use it".
Recursion is often handy to implement algorithms that are very recursive
in nature, but one should be careful to not use too much stack space.
(Generally speaking C++ compilers do not perform tail recursion
optimizations. I'm not completely sure why.)
If your recursion depth is O(log n), then it's usually safe. If it starts
being O(n), then it's more worrisome. (Well, depending on the expected
amount of data, of course.)
Usually recursion is also slower than an equivalent iterative solution
(*especially* if the iterative solution works with O(1) extra memory.)
> "Registers are a special area of memory built right into the CPU."
> Erm...
Even C programmers stopped worrying about CPU registers somewhere in the
early 80's. In C++ they have never been an issue. It's a headache of the
compiler, not the programmer.
> Still, it does answer something I've always wondered about: What *is*
> the C calling convention?
It actually depends on the OS.
You don't need to worry about calling conventions unless you are
implementing something really, *really* low-level. Machine-code level.
(One example would be if you are writing a compiler.)
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
From: Warp
Subject: Re: Teach yourself C++ in 21 strange malfunctions
Date: 17 Apr 2012 10:03:32
Message: <4f8d7834@news.povray.org>
|
|
 |
|  |
|  |
|
 |
Invisible <voi### [at] dev null> wrote:
> When I looked at my function, I found I'd written "it->second;" rather
> than "return it->second;". Not only is this apparently legal, it doesn't
> even generate a compile-time /warning/.
What compiler would that be?
int test()
{
}
test.cc:3:13: warning: no return statement in function returning non-void
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 17/04/2012 02:40 PM, Warp wrote:
> Orchid Win7 v1<voi### [at] dev null> wrote:
>> Then there's a cryptic reference to the fact that iostream and
>> iostream.h aren't the same, but the differences are "subtle, exotic, and
>> beyond the scope of an introductory primer".
>
> One is standard, the other isn't. What is there more to explain?
The book doesn't actually mention this fact. It seems to suggest that
you just use whichever one you fancy. And then says something about "but
we're going to use iostream.h for compatibility reasons".
So I'm presuming iostream is the standards-compliant one?
>> Anyway, apparently main() must always return int. It is against the ANSI
>> standard for it to return void. (No mention of it having parameters.
>> Indeed, even the return value is described as an "obscure feature which
>> we won't make use of".)
>
> I don't think it would have been very hard to say something like "the
> return value is used by the operating system as a success/failure value"
> and then explain that 0 means success and other values can be used as a
> failure code. (It is actually important to know this especially when
> creating a command-line program. The return value of main() is
> significant.)
Yeah, an exit code is not exactly an "obscure feature". I can understand
the book not using it, but that doesn't mean the same as being useless.
>> Then there's some mumbo-jumbo about how you can use cout "to do
>> addition", and how when you do count<< 8+5, then "8+5 is passed to
>> cout, but 13 is what is actually printed". Nice, clear explanation,
>> that. :-P
>
> Actually "8+5" is not being passed to cout.
Quite. The text completely fails to explain what's /actually/ happening.
A bit later on it starts talking about how "the compiler" calls XYZ when
you do ABC. Obviously, the compiler doesn't call anything; it just
generates code. :-P
> Anyways, it's not like it's important.
It is if you want to form an understanding of what the stuff you're
typing in actually /means/. The text makes it sound like adding is
somehow special to cout, which clearly it isn't. You can do this with
/any/ function call.
>> And then it starts talking about types. Apparently C++ adds a new "bool"
>> type, which is supposed to be 1 byte.
>
> I don't think the standard defines the size of bool. Most compilers
> probably make it 1.
I have a sinking feeling you're right.
>> Apparently "char" doesn't mean
>> character at all, it means a 1-byte integer (and by default, a signed one).
>
> The standard only guarantees that sizeof(char) is 1, but not that char
> is 1 byte. (It is possible for char to be larger in some systems. It just
> means that everything else is then a multiple of that size.)
>
> The standard also lets the signedness of char as implementation-defined.
> (In most practical systems it's signed.)
Oh... goodie.
> (Curiously, "char" and "signed char" are two *different* types in C and
> C++ even if "char" is signed, while for example "int" and "signed int" are
> completely synonymous and the "signed" keyword is redundant in the latter
> case. This comes from the prehistoric dark ages of C.)
Wait... I didn't even know you could /do/ that! o_O
> Nope. The standard does not say that. The only thing the standard says
> is that:
>
> sizeof(char)<= sizeof(short)<= sizeof(int)<= sizeof(long)
>
> and that sizeof(char) = 1 (which does not mean "1 byte", but "1 indexable
> memory unit".)
>
> (Yes, it is possible and standard-conforming for char to be as large
> as long.)
>
> In practice in most 32-bit systems short will be 16 bits and int/long
> will be 32 bits. In most 64-bit systems it will be the same except that
> long will be 64 bits.
>
> Curiously, the new standard specifically states that the new "long long"
> type has to be at least 64 bits. (The new standard also defines official
> typedefs for integrals of specific sizes.)
Ouch. My head.
> "Never use int" is a silly thing to say.
>
> If you need an integral that's the natural word size of the target system,
> use int. If you need an integral with a specific number of bits, use one
> of the new standard typedefs.
Now /that/ actually makes sense. Where are these typedefs located? Do
you have to include them specifically, or...?
> Use "long long" for an integral of at least
> 64 bits (at least if your compiler supports C++11). There's no standard
> support for larger integrals (because they are not supported by CPUs).
Not supported _yet_. ;-)
> C hackers don't want the extra clock cycle to initialize a variable
> which will be immediately assigned a new value anyways.
I figured.
> As a side effect you get all kinds of weird behavior if you forget to
> initialize a variable.
Yeah, it's great, isn't it? ;-)
I had hoped for maybe a compile-time warning. I haven't actually tried
it to see if I get one though...
(Java actually refuses to compile your code if it can't satisfy itself
that /every/ variable is initialised. Which gets annoying when every
variable /is/ initialised before use, but the compiler can't prove it...)
>> Apparently assigning a double to an int is only a /warning/, not a
>> compile-time error. The book helpfully fails to specify how the
>> conversion is actually done.
>
> The integral part of the value is assigned to the int.
So... it always rounds towards zero?
>> is a perfectly valid statement in C++. On the other hand, it also means that
>
>> while (x[i] = y[i--]) ;
>
>> is perfectly valid. You sick, sick people.
>
> I think that's Undefined Behavior because the same variable is being
> modified and referenced more than once in the same expression.
Aren't expressions guaranteed to execute left-to-right?
> Even if it isn't UB, better not do it like that.
But that's just it. All C programmers always code in this kind of style.
It's part of what makes C so terrifying to try to read.
>> In most programming languages, performing division promotes integers to
>> reals. But not in C++, apparently.
>
> C is a wrapper around assembly, and assembly supports integral division.
> Hence dividing integers performs integral division. Oftentimes you *want*
> integral division
Most languages seem to provide a separate operator for that. But sure, OK.
>> At this point, we
>> are told that there's two ways to convert something to an double:
>
>> double x = (double)y;
>
>> double x = static_cast<double>y;
>
>> Apparently the former is bad, and the latter is good. No indication as
>> to why, it just is.
>
> The former casts *anything* into a double, while the latter casts only
> compatible types. (Which means that the latter will give you a compiler
> error if you try to cast from an incompatible type by mistake.)
Now why the hell they couldn't just /say/ that I don't know...
>> Next we learn that false=0, and true /= 0. (Christ, I'm /never/ going to
>> remember that!) Apparently there's a new bool type, but details are thin
>> as to what the exact significance of this is.
>
> You are never going to remember that 0 is false?
I know that zero is one thing, and everything else is the other thing.
But I always struggle to remember whether zero means true or false. The
solution, of course, is to never ever use integers as bools.
>> Then we learn about if/then, if/then/else, and finally ?: is
>> demonstrated, without once mentioning how it's different from
>> if/then/else. (I.e., it only works on expressions, not statements. Oh,
>> but wait! Silly me, statements /are/ expressions...)
>
> ?: cannot contain blocks of code, and both branches much evaluate to
> the same type. No such limitation for if/then/else.
Quite. The book doesn't bother mentioning any of that.
>> Bizarrely, if you don't specify a return type, it defaults to int. Not,
>> say, void. :-o
>
> Not in standard C++ (where it's an error).
Oh thank god!
>> Then we learn about global variables. Apparently if you write a variable
>> outside of any block, it's global. No word on exactly when it's
>> initialised, or precisely what "global" actually means. For example, I'm
>> /guessing/ the variable is only in-scope /below/ the line where it's
>> defined. That's how functions work, after all.
>
> If you define a variable (or function) in the global namespace, it will
> be visible in the entire program. (Yes, you can access it from a different
> compilation unit. You just need to declare it with "extern" in that other
> compilation unit to do that.)
>
> The problem with global variables is, obviously, name clashes. You'll
> start getting weird linker errors about duplicate names if you make a habit
> of using lots of globals (and then happen to use the same name in two
> compilation units).
From what I'm seeing, just having multiple compilation units is a
nightmare. (That's one of the reasons I'm reading this book. I'm hoping
it's going to explain how to do this stuff properly.)
> (Also, from a design point of view, global variables decrease abstraction,
> which is bad.)
From a design point of view, global variables are a terrible idea. But
that the book bothers to explain why.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 17/04/2012 03:03 PM, Warp wrote:
> Invisible<voi### [at] dev null> wrote:
>> When I looked at my function, I found I'd written "it->second;" rather
>> than "return it->second;". Not only is this apparently legal, it doesn't
>> even generate a compile-time /warning/.
>
> What compiler would that be?
>
> int test()
> {
> }
>
> test.cc:3:13: warning: no return statement in function returning non-void
#include <iostream>
#include <string>
std::string test()
{
}
int main()
{
std::cout << test();
return 0;
}
orphi@linux-z30b:~/Work/Logic-01> make Test
g++ Test.cpp -o Test
orphi@linux-z30b:~/Work/Logic-01> ./Test
Segmentation fault
orphi@linux-z30b:~/Work/Logic-01> g++ --version
g++ (SUSE Linux) 4.5.1 20101208 [gcc-4_5-branch revision 167585]
Copyright (C) 2010 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 17/04/2012 03:00 PM, Warp wrote:
> Invisible<voi### [at] dev null> wrote:
>> "Note that inline functions can bring a heavy cost. If the function
>> is called 10 times, the inline code is copied into the calling functions
>> each of those 10 times. The tiny improvement in speed you might achieve
>> is more than swamped by the increase in the size of the executable
>> program.
>
> He seems to think that the 'inline' keyword forces the compiler to inline.
> It doesn't. The compiler is completely free to not inline it, if it decides
> that it would be detrimental.
He even /says/ that a few paragraphs later. "Inline is a hint, which the
compiler may ignore."
> As for increasing the size of the executable, who cares? If the executable
> gets a few hundreds of bytes larger, big deal.
Yeah, that's the really puzzling bit. I mean, unless the function is
huge [which is a bad idea anyway], or is called from a bazillion places,
why would inlining it "bring its own performance costs"? I don't get that.
> The 'inline' keyword has a secondary, but much more important role,
> though: It's an instruction for the compiler that says, basically, "if
> this function appears in more than one compilation unit, don't give me
> a linker error; instead merge them into one".
OK, /that/ sounds rather more significant.
> Anyways, 'inline' should usually only be used for very short functions
> that are absolutely crucial for speed. Otherwise there's little benefit.
The book claims that if you write a function body inside a class
definition, that makes the method inline. Is this true? I thought there
was no difference either way...
>> Now, I'm used to programming languages where the decision to inline
>> something or not is down to the compiler. It's not something an
>> application programmer would ever have to worry about. And it seems that
>> the inline directive is only a "hint" in C++ anyway, so I have to
>> wonder, whether this particular directive is now obsolete.
>
> Some newer compilers (such as the newest version of gcc) are able to
> inline functions between compilation units. However, this is a rare,
> quite advanced feature. (AFAIK only gcc implements this so far.)
OK. Presumably /within/ a single compilation unit it's already going to
inline anything it thinks is worth it though. (?)
> Traditionally, if you need a short function to be as fast as possible,
> you need to define it in the module's header file, and then it *must* be
> declared 'inline' (or else you'll get linker errors).
Right.
>> I love the dire warnings that you could use a number less than 15,
>> because otherwise the program might consume a vast amount of memory.
>> (For goodness' sake, how much RAM does 15 stack frames take up?!)
>
> That would probably be 15^2. The author might have been using a 16-bit
> DOS compiler.
He does mention DOS several times, yes.
Even so, there might be 15^2 function calls, but only at most 15 of them
will be /active/ simultaneously - which means only 15 stack frames at
once. No?
>> In other words, yet again, "now you know how this works, you don't need
>> to actually use it".
>
> Recursion is often handy to implement algorithms that are very recursive
> in nature, but one should be careful to not use too much stack space.
> Usually recursion is also slower than an equivalent iterative solution
> (*especially* if the iterative solution works with O(1) extra memory.)
Well, yes. As I understand it, by default C++ doesn't reserve a whole
lot of stack space, so you're likely to overflow it quite quickly. And
as you say, being non-recursive means you skip all the overhead of
jumping into and out of functions, which is faster. (It probably enables
more compiler optimisations too, I wouldn't wonder...)
>> Still, it does answer something I've always wondered about: What *is*
>> the C calling convention?
>
> It actually depends on the OS.
>
> You don't need to worry about calling conventions unless you are
> implementing something really, *really* low-level. Machine-code level.
> (One example would be if you are writing a compiler.)
I'm a curious soul. I think to have some idea how things work, even if I
don't know all of the details... ;-)
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Invisible <voi### [at] dev null> wrote:
> Now /that/ actually makes sense. Where are these typedefs located? Do
> you have to include them specifically, or...?
IIRC they are in <cstdint>.
> I had hoped for maybe a compile-time warning. I haven't actually tried
> it to see if I get one though...
Some compilers will give you a warning if they think that a variable
is being used uninitialized, but given that the general problem of
determining that is unsolvable, it's not fool-proof.
There are some tools (such as valgrind) that will tell you at runtime.
> Aren't expressions guaranteed to execute left-to-right?
Expressions with side-effects can happen in any order. The compiler is
free to optimize expressions in any way it likes (as long as the result
is always the same if the expression had no multiple side-effects on the
same variable).
For example, if you do a "table[i++] = i;" the compiler can decide to
increment the 'i' before it assigns it to that location, or after the
entire statement is done. The general solution to that is: Don't do it.
> > Even if it isn't UB, better not do it like that.
> But that's just it. All C programmers always code in this kind of style.
> It's part of what makes C so terrifying to try to read.
C programmers (at least competent ones) do not have multiple side-effects
on the same variable inside the same expression. They may have multiple
side-effects on *different* variables, which is ok. For example:
while(*dest++ = *src++) {}
There are two side-effects there, but they are operating on different
variables, so there's no ambiguity.
> I know that zero is one thing, and everything else is the other thing.
> But I always struggle to remember whether zero means true or false. The
> solution, of course, is to never ever use integers as bools.
What do you think this will print?
bool b = true;
std::cout << b << std::endl;
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> I think you need to be working with very specific types of problems to
>> warrant using Haskell, which isn't to say nobody uses it.
>
> What, you mean like programs involving complex data manipulations?
> Problems where you want to actually get the correct answer? Problems
> where you'd like to be able to still understand the code in two years'
> time? Because, to me, that sounds like a pretty /huge/ problem domain. ;-)
Give a specific example then, of a real commercial problem where
selecting Haskell would be the best choice. I'm not saying none exist,
just wondering exactly what type of software problem Haskell would excel
at. Presumably it's not making a 3D game or an application that is
mostly GUI.
> It's sad, really. You can use C or Java or whatever, which is horrible
> to code in but lets you actually get stuff done. Or you can code in
> Haskell, which is a joyful celebration of how programming should be, but
> then it's a nightmare to actually interact with the outside world... I
> keep hoping that some day this situation will be fixed. But I doubt it.
In the end companies that are trying to make money will just use
whichever system lets them solve the problems as quickly as possible.
This results in all manner of different languages being used (even
Haskell!). But I think the reason you imagine C++/Java/C# being so
popular is that the huge markets of software don't match with Haskell.
Desktop software needs a familiar GUI and easy documented access to
APIs. Apps for phones need good access to hardware (and usually the OS
maker has chosen a language for you). Games need high performance and
good access to hardware APIs.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Invisible <voi### [at] dev null> wrote:
> > As for increasing the size of the executable, who cares? If the executable
> > gets a few hundreds of bytes larger, big deal.
> Yeah, that's the really puzzling bit. I mean, unless the function is
> huge [which is a bad idea anyway], or is called from a bazillion places,
> why would inlining it "bring its own performance costs"? I don't get that.
In fact, inlining can actually sometimes reduce the size of the executable
(because a function call may be replaced with an expression that gets
calculated at compile time and optimized away).
> > Anyways, 'inline' should usually only be used for very short functions
> > that are absolutely crucial for speed. Otherwise there's little benefit.
> The book claims that if you write a function body inside a class
> definition, that makes the method inline. Is this true? I thought there
> was no difference either way...
A function definition inside a class definition is implicitly 'inline'
(without having to explicitly use the keyword; you could specify it, but
it would be redundant.)
Likewise template functions are implicitly 'inline' without having to
explicitly say so.
> Even so, there might be 15^2 function calls, but only at most 15 of them
> will be /active/ simultaneously - which means only 15 stack frames at
> once. No?
You may be right.
> Well, yes. As I understand it, by default C++ doesn't reserve a whole
> lot of stack space, so you're likely to overflow it quite quickly.
It depends on the OS. (In most unixes you can actually set how much
stack is given to a process.)
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
From: Warp
Subject: Re: Teach yourself C++ in 21 strange malfunctions
Date: 17 Apr 2012 10:36:45
Message: <4f8d7ffd@news.povray.org>
|
|
 |
|  |
|  |
|
 |
Invisible <voi### [at] dev null> wrote:
> orphi@linux-z30b:~/Work/Logic-01> make Test
> g++ Test.cpp -o Test
You need to put a "CXXFLAGS=-Wall -O2" in your Makefile. (With Gnu make
that's probably the only think that you need to put there.)
Of compile it directly with "g++ -Wall -O3 Test.cpp -o Test".
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 17/04/2012 03:26 PM, Warp wrote:
> Invisible<voi### [at] dev null> wrote:
>> Now /that/ actually makes sense. Where are these typedefs located? Do
>> you have to include them specifically, or...?
>
> IIRC they are in<cstdint>.
A quick Google search indicates that cstdint defines std::int8_t,
std::int16_t and so on, plus uint versions (presumably unsigned). It
also defines std::int_fast8_t and friends, std::int_least8_t and so on,
a std::intmax_t and a std::intintptr_t.
>> I had hoped for maybe a compile-time warning. I haven't actually tried
>> it to see if I get one though...
>
> Some compilers will give you a warning if they think that a variable
> is being used uninitialized, but given that the general problem of
> determining that is unsolvable, it's not fool-proof.
>
> There are some tools (such as valgrind) that will tell you at runtime.
I may yet end up having to investigate valgrind. It seems it's the only
reliable way to discover if your code leaks memory...
>> Aren't expressions guaranteed to execute left-to-right?
>
> Expressions with side-effects can happen in any order. The compiler is
> free to optimize expressions in any way it likes (as long as the result
> is always the same if the expression had no multiple side-effects on the
> same variable).
I see. So that's why programs tend to break if you turn the optimisation
settings up too high?
>> But that's just it. All C programmers always code in this kind of style.
>> It's part of what makes C so terrifying to try to read.
>
> C programmers (at least competent ones) do not have multiple side-effects
> on the same variable inside the same expression. They may have multiple
> side-effects on *different* variables, which is ok. For example:
>
> while(*dest++ = *src++) {}
>
> There are two side-effects there, but they are operating on different
> variables, so there's no ambiguity.
It still makes my head hurt. >_<
> What do you think this will print?
>
> bool b = true;
> std::cout<< b<< std::endl;
Well, I guess now that C++ has /names/ for true and false, I don't have
to worry about it.
Is bool still regarded as an alias to an integer type? Or does it really
get treated as a separate, distinct type?
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> why would inlining it "bring its own performance costs"? I don't get that.
>
> In fact, inlining can actually sometimes reduce the size of the executable
> (because a function call may be replaced with an expression that gets
> calculated at compile time and optimized away).
That's what I figured.
>> The book claims that if you write a function body inside a class
>> definition, that makes the method inline. Is this true? I thought there
>> was no difference either way...
>
> A function definition inside a class definition is implicitly 'inline'
> (without having to explicitly use the keyword; you could specify it, but
> it would be redundant.)
Hmm, OK. So is it a good idea to include simple accessor methods in a
header file then? (The book seems to suggest it is.)
> Likewise template functions are implicitly 'inline' without having to
> explicitly say so.
Well, by definition a template generates a new copy of the function each
time you use it, no?
>> Even so, there might be 15^2 function calls, but only at most 15 of them
>> will be /active/ simultaneously - which means only 15 stack frames at
>> once. No?
>
> You may be right.
I usually am. :^)
>> Well, yes. As I understand it, by default C++ doesn't reserve a whole
>> lot of stack space, so you're likely to overflow it quite quickly.
>
> It depends on the OS. (In most unixes you can actually set how much
> stack is given to a process.)
Yeah, I should think most times you can throw a compiler switch, or ask
the OS to reserve more at run-time.
PS. I can't believe I just wrote "I usually am". Heh.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Invisible <voi### [at] dev null> wrote:
> > Likewise template functions are implicitly 'inline' without having to
> > explicitly say so.
> Well, by definition a template generates a new copy of the function each
> time you use it, no?
No. A new version is created for each used *type*.
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 17/04/2012 04:06 PM, Warp wrote:
> Invisible<voi### [at] dev null> wrote:
>>> Likewise template functions are implicitly 'inline' without having to
>>> explicitly say so.
>
>> Well, by definition a template generates a new copy of the function each
>> time you use it, no?
>
> No. A new version is created for each used *type*.
Oh, I see. I'm still thinking of macro expansion, aren't I? OK.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
>> What, you mean like programs involving complex data manipulations?
>> Problems where you want to actually get the correct answer? Problems
>> where you'd like to be able to still understand the code in two years'
>> time? Because, to me, that sounds like a pretty /huge/ problem domain.
>> ;-)
>
> Give a specific example then, of a real commercial problem where
> selecting Haskell would be the best choice. I'm not saying none exist,
> just wondering exactly what type of software problem Haskell would excel
> at. Presumably it's not making a 3D game or an application that is
> mostly GUI.
> In the end companies that are trying to make money will just use
> whichever system lets them solve the problems as quickly as possible.
> This results in all manner of different languages being used (even
> Haskell!). But I think the reason you imagine C++/Java/C# being so
> popular is that the huge markets of software don't match with Haskell.
> Desktop software needs a familiar GUI and easy documented access to
> APIs. Apps for phones need good access to hardware (and usually the OS
> maker has chosen a language for you). Games need high performance and
> good access to hardware APIs.
I think /everybody/ wants to write code which is robust, reliable,
portable and maintainable. The problem, as you say, is that usually
getting access to the native resources is usually a highER priority than
writing beautiful code.
If you release a Windows application which requires you to install GTK
before it will work, nobody is going to care how beautiful the code is.
(Except your dev team.) They're all going to think it looks like crap.
And if you release an application written in low-level C and structured
like spaghetti, nobody will care as long as it actually works reasonably
well and it looks nice.
A guess fundamentally, if you write your application in C or C++, then
you can use any code library that has ever been written, interface with
any system, do absolutely anything you want. If you write your
application in Haskell... then in theory you can do the same. In
reality, it's going to take forever to write bindings to an external
library, and because the binding is so low-level, you lose most if not
all of the benefits of Haskell anyway.
If there ever comes a day when Haskell ships out of the door with
top-quality libraries for doing most or all of the things that a typical
developer would want to get done, then maybe Haskell will start to
become popular. I don't see that day being particularly soon.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 17/04/2012 03:36 PM, Warp wrote:
> Invisible<voi### [at] dev null> wrote:
>> orphi@linux-z30b:~/Work/Logic-01> make Test
>> g++ Test.cpp -o Test
>
> You need to put a "CXXFLAGS=-Wall -O2" in your Makefile.
OK, /now/ I at least get a warning.
I'm still a bit baffled that this is a valid thing to do, however...
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
> If there ever comes a day when Haskell ships out of the door with
> top-quality libraries for doing most or all of the things that a typical
> developer would want to get done, then maybe Haskell will start to
> become popular.
The problem is that F# exists already, and I guess you wouldn't call it
"popular" in the way that you would like Haskell to become. So Haskell
would need to become, in some way, superior to F# in order to become
popular.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 17/04/2012 04:49 PM, scott wrote:
>> If there ever comes a day when Haskell ships out of the door with
>> top-quality libraries for doing most or all of the things that a typical
>> developer would want to get done, then maybe Haskell will start to
>> become popular.
>
> The problem is that F# exists already, and I guess you wouldn't call it
> "popular" in the way that you would like Haskell to become. So Haskell
> would need to become, in some way, superior to F# in order to become
> popular.
Haskell is /already/ superior to F#. ;-)
For a start, F# is functional in the same way that C++ is
object-oriented. I.e., not very. F# is a normal OO language with a few
slightly functional ideas bolted on the side as an afterthought.
But in all seriousness: Haskell will never be popular. Writing clean,
maintainable code just isn't a high priority. Bashing out code as fast
as possible is a high priority. Producing six point-releases per
calendar month is a high priority. Being paid per LoC is a high
priority. Nobody will ever want to use Haskell.
Still, at least if Haskell shipped with decent libraries, *I* could
still enjoy using it. :-P
Post a reply to this message
|
 |
|  |
|  |
|
 |
From: Warp
Subject: Re: Teach yourself C++ in 21 strange malfunctions
Date: 17 Apr 2012 12:07:21
Message: <4f8d9539@news.povray.org>
|
|
 |
|  |
|  |
|
 |
Invisible <voi### [at] dev null> wrote:
> For a start, F# is functional in the same way that C++ is
> object-oriented. I.e., not very. F# is a normal OO language with a few
> slightly functional ideas bolted on the side as an afterthought.
When will we see the Haskell# language?
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Invisible escreveu:
> ...and then I feel depressed because I'm the only person in the UK who
> programs in Haskell
you and at least Simon Peyton Jones.
Post a reply to this message
|
 |
|  |
|  |
|
 |
From: nemesis
Subject: Re: Teach yourself C++ in 21 strange malfunctions
Date: 17 Apr 2012 15:26:59
Message: <4f8dc403@news.povray.org>
|
|
 |
|  |
|  |
|
 |
scott escreveu:
> If Haskell had a decent IDE and easy documented access to the rest of
> the system I might consider using it. But then F# exists already and I
> haven't paid much attention to that so far...
IDEs are only really useful for OO languages. You know, you have a
variable holding an instance of a class, then you type "." and get a
list of methods available... no such thing in functional programming
where the order is reversed: you have a function and want to apply
arguments to it. You may list arguments that match that function
definition and you may even know their types (assuming "intellisense"
got type inference), but most likely you're not directly applying those
arguments to the function, but applying some other function to it first.
It sounds too much of hassle to use "intellisense" in those situations...
I fear IDEs are really only useful at getting away with lesser
languages' weaknesses, AKA boilerplate cruft to make the compiler happy.
In Java, most of the IDE is used not just for that but also to handle
all the xml needed, since it's the only DSL known to java-heads...
so, all that would seem to rest of usefulness for an IDE is project
management. Here too it proves pretty useless as it's only really
needed to manage huge bloated projects full of boilerplate and xml.
Post a reply to this message
|
 |
|  |
|  |
|
 |
From: Warp
Subject: Re: Teach yourself C++ in 21 strange malfunctions
Date: 17 Apr 2012 15:51:14
Message: <4f8dc9b2@news.povray.org>
|
|
 |
|  |
|  |
|
 |
Invisible <voi### [at] dev null> wrote:
> I'm still a bit baffled that this is a valid thing to do, however...
There's some baggage from C that would have better been dropped, but
as you may know, backwards compatibility can be a real b***h sometimes...
It can be argued using the same logic as with uninitialized variables,
though: There are situations where execution never reaches the end of the
function, and hence having a 'return' statement there would be useless.
In most situations putting such a useless 'return' there is only a minor
inconvenience, but in theory it could be more complicated. Also, it makes
the function larger, so the 80's C hackers didn't like that (in the same
way as they didn't like the idea of spending a clock cycle to initialize
a variable with a value that would immediately be overwritten anyways).
This would be an example of such a function:
std::string foo(int parameter)
{
assert(parameter >= 0 && parameter < 4);
switch(parameter)
{
case 0: return "Hello";
case 1: return "there";
case 2: return "world";
case 3: return "!";
}
// Execution will *never* reach here
// It's valid to omit a 'return'
}
--
- Warp
Post a reply to this message
|
 |
|  |
|  |
|
 |
From: Le Forgeron
Subject: Re: Teach yourself C++ in 21 strange malfunctions
Date: 17 Apr 2012 16:46:16
Message: <4f8dd698$1@news.povray.org>
|
|
 |
|  |
|  |
|
 |
Le 17/04/2012 21:51, Warp nous fit lire :
> the 80's C hackers didn't like that (in the same
> way as they didn't like the idea of spending a clock cycle to initialize
> a variable with a value that would immediately be overwritten anyways).
It was a time where memory access was done by putting the address on the
address bus, and the data was read/write on the data bus (and a wire was
dedicated to indicate if it was a read or write).
A time in which the memory respond time was faster than the CPU clock.
A time you could know the number of cycles to perform an addition, a
multiplication or a division (on integer). And gains a few cycles by
reordering expression.
A time I remember!
And it cost one cycle (may be a bit more, I do not remember the timing
for a move.l) to write a zero to a data bus-wide variable, but as many
cycles for an array. You do not want to waste 40 cycles to erase an
array of 40 int.
You already wasted a cycle to increase the stack usage, and by entering
a function you wasted a few more cycle saving a few registers on it too.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
Le 17/04/2012 14:13, Invisible a écrit :
> Obviously this /isn't/ what's so special about classes. The /actual/
> benefits don't appear to be mentioned.
The benefit of class over a simple struct/collection is in the
private/protected parts, and the mandatory centralisation of the
prototypes of all related functions (until you start playing with
friend, but that's another story).
The point in class is to separate the interface (how the outside world
see me and use me) from the implementation (how I do it internally).
Once exposed, the public interface must remain (it can be expanded, but
not changed drastically).
The implementation can be changed at any time.
And then we are going to enter some holy wars about automatic getter &
setter, and static member in class.
--
A good Manager will take you
through the forest, no mater what.
A Leader will take time to climb on a
Tree and say 'This is the wrong forest'.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 17/04/2012 08:09 PM, nemesis wrote:
> Invisible escreveu:
>> ...and then I feel depressed because I'm the only person in the UK who
>> programs in Haskell
>
> you and at least Simon Peyton Jones.
Yeah - I should go visit that guy sometime...
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 17/04/2012 05:07 PM, Warp wrote:
> Invisible<voi### [at] dev null> wrote:
>> For a start, F# is functional in the same way that C++ is
>> object-oriented. I.e., not very. F# is a normal OO language with a few
>> slightly functional ideas bolted on the side as an afterthought.
>
> When will we see the Haskell# language?
Well, a while back somebody did do a Haskell to .NET bridge for their
PhD thesis.
(A /bridge/ is of course not the same thing as compiling to CIL. The
Haskell stuff runs as normal, it's just that it can "talk to" stuff
running on the .NET platform.)
Naturally, being a PhD thesis, it's proof-of-concept, not
production-grade. And, I would imagine, no longer maintained. (Not that
I suppose the /code/ was ever publicly released. The /thesis/ was, but I
don't know about the runnable code.)
In a similar vein, one of the experimental Haskell compilers has a
JavaScript back-end. As in, you write your Haskell program, compile it,
and you get (several KB of) normal JavaScript which will run in any web
browser. Again, not exactly production-grade, but interesting.
I think somebody somewhere once had a Haskell to Java compiler. (Or,
more likely, a "small subset of Haskell to Java compiler".) Highly
unfinished, of course.
Perhaps it would make an interesting research project... Maybe I should
look up how either Java bytecodes or the CIL works, and write some code
to target it.
Naturally, being able to run on either the JVM or the CLR wouldn't be
interesting unless it's also simple and easy to access the existing
class libraries. And that's another interesting project.
Post a reply to this message
|
 |
|  |
|  |
|
 |
From: Invisible
Subject: Re: Teach yourself C++ in 21 strange malfunctions
Date: 18 Apr 2012 04:04:14
Message: <4f8e757e@news.povray.org>
|
|
 |
|  |
|  |
|
 |
On 17/04/2012 08:51 PM, Warp wrote:
> Invisible<voi### [at] dev null> wrote:
>> I'm still a bit baffled that this is a valid thing to do, however...
>
> There's some baggage from C that would have better been dropped, but
> as you may know, backwards compatibility can be a real b***h sometimes...
Don't we all know it. ;-)
(Haskell isn't as ancient as C, so fortunately it has much less of this.
It /does/ have it, however...)
> It can be argued using the same logic as with uninitialized variables,
> though: There are situations where execution never reaches the end of the
> function, and hence having a 'return' statement there would be useless.
Sure. But like I said, the Java compiler seems to detect this. If
doesn't just look at a function and say "does it contain a return
statement somewhere?" It actually statically analyses every possible
flow of control, and checks that every individual one ends with a return
(or throws an exception, which is also a valid way to terminate a function).
Of course, it's not perfect. Plausibly you could have if branches such
that a particular sequence of branches is impossible due to the
conditions in those branches, but the compiler wouldn't "see" that and
would still insist that you have a branch that doesn't terminate
properly. But I haven't seen that happen yet.
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|  |
|
 |
On 18/04/2012 07:24 AM, Le_Forgeron wrote:
> Le 17/04/2012 14:13, Invisible a écrit :
>> Obviously this /isn't/ what's so special about classes. The /actual/
>> benefits don't appear to be mentioned.
>
> The benefit of class over a simple struct/collection is in the
> private/protected parts, and the mandatory centralisation of the
> prototypes of all related functions.
Indeed. Anybody who knows any OO theory will understand this. But,
unfortunately, anyone who reads this book will have no idea.
Hey Warp, you ever think about writing a book? I bet you could do a
better job than this idiot...
Post a reply to this message
|
 |
|  |
|  |
|
 |
|
 |
|  |
|
 |