Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Some errors in MIT's intro C++ course

304 views
Skip to first unread message

Alf P. Steinbach /Usenet

unread,
Sep 8, 2010, 3:15:45 PM9/8/10
to
[This article is cross-posted to comp.lang.c++ and comp.programming]

I was a bit shocked when I saw this a few days ago. I then used the MIT Open
Courseware feedback option to inform them of the problems, where I explained
things at about the same detail level as below, and was told that if a response
was required it would be given within two business days. Well, either there's a
holiday on in the MIT area, or MIT doesn't think this is problematic.

This is a very short intro course, covering only basics, so the error frequency
is quite high.


Dunietz, Jesse, Radhika Malik, and Tanmay Kumar, 6.096 Introduction to C ,
January IAP 2009. (Massachusetts Institute of Technology: MIT OpenCourseWare),
http://ocw.mit.edu (Accessed 08 Sep, 2010). License: Creative Commons BY-NC-SA

http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-096-introduction-to-c-january-iap-2009/

6.096 Introduction to C++
As taught in: January IAP 2009

Level:
Undergraduate / Graduate

Course Description
This course is designed for undergraduate and graduate students in science,
social science and engineering programs who need to learn fundamental
programming skills quickly but not in great depth. The course is ideal for
undergraduate research positions or summer jobs requiring C++. It is not a class
for experienced programmers in C++. Students with no programming background are
welcome. Topics include control structures, arrays, functions, classes, objects,
file handling, and simple algorithms for common tasks.
This course is offered during the Independent Activities Period (IAP), which is
a special 4-week term at MIT that runs from the first week of January until the
end of the month.

*** Lecture 1 "Basics"

Page 1/6 "Header files"

INCORRECT. <iostream.h> is not a standard C++ header.
The corresponding standard C++ header is <iostream>.

Page 1/16 "Unary and binary operators"

INCORRECT. "To nullify a variable, you can write the exclamation point to its
left" is meaningless.
!a is a value operation, not an operation on a variable. It does not nullify (in
the ordinary meaning of that word), it produces the logical negation of a
boolean value. The latter is possibly just a terminological issue, but very
misleading.

Page 1/18 "Data types in C++"

MISLEADING. The "Range" column lists ranges of various data types with a Windows
C++ compiler, without stating that it's a Windows C++ compiler, and no context
implying that. In standard C++ these are not guaranteed minimum ranges. Nor are
they maximum ranges.

Page 1/19 "Data types in C++"
INCORRECT. type bool is said to have size "1 bit". The minimum size in C++ is 1
byte. Anyway, it's meaningless.

Page 1/20 "Variable declaration and naming conventions"
WPFU. Word processing foul-up: `a´ is not valid C++ syntax. 'a' is valid.
EVIL. Teaching evil practice: "Constants are all in uppercase". Every good C++
FAQ, including Bjarne Stroustrup's own, and every good C++ textbook, tells you
that in C++ all uppercase should be reserved for macros. All uppercase constants
are a Java/Python/etc. convention (where it can do some good), not a C++
convention (where it causes needless name collisions).

Page 1/22 "Starting to write programs"
WPFU. Word processing foul-up. The double-quote characters used are not
representable in Latin-1 so I can't quote it here, but it's not valid C++. Valid
C++ would be e.g. "Hello".


*** Lecture 3 "Functions"

Page 3/2 "char vs. char*"

INCORRECT. The second paragraph's first statement, "A char *, or a string,
stores a series of 0 or more characters", is incorrect. char* is a pointer to char.

INCORRECT. The second paragraph's second statement, "A constant char * value is
indicated with "double quotes"", is incorrect. A string literal denotes an array
of characters. An array is not a pointer (this confusion is repeated in a later
lecture).

Page 3/7

INCORRECT. The statement "Trying to change the value of number in the body of
square would be a syntax error" is incorrect. It would be an error, yes, but it
would not be a syntax error.


*** Lecture 4 "Arrays"

Page 4/6 "Initializing arrays"

WPFU. Word-processing foul-up of quote marks.

Page 4/11 "Linear search in arrays"
Page 4/16 "Binary search code snippet"

WPFU. Word processing foul-up of indentation (not really an error but ungood).
EVIL. Teaching evil practices (uppercase single letter names, comparing bool to
true/false, so on).


*** Lecture 5 "Pointers"

Page 5/4 "Pointers and arrays"

INCORRECT. "The name of an array is in fact just a pointer to the first element
in the array". It is not (e.g. sizeof(a), or passing an array by reference).
INCORRECT. "Passing an array is really passing a pointer". In C++ arrays can be
passed by reference.

Page 5/5 "Null, uninitialized, and deallocated pointers"

DEBATABLE. "... a null pointer ... is an invalid pointer". Neither C++98 nor
C++0x defines "invalid pointer", but the common terminology is to not regard a
nullpointer as an invalid pointer. Instead that term is reserved for pointers
where rvalue conversion of the pointer, causes UB.

INCORRECT. "Any attempt to dereference it will result in a runtime error".
First, a nullpointer can be safely dereferenced in a typeid expression. Second,
C++ does not define the result of dereferencing nullpointers in other contexts,
it's Undefined Behavior. Third, C++ has no notion of runtime error (it's just
one possible effect of UB).

Page 5/5 "char * and char[]"

INCORRECT. "Arrays of chars and pointers to char are interchangeable". No,
they're not, e.g. sizeof(a) or passing an array by reference.

INCORRECT. "[modifying a string constant] is either a syntax error or a runtime
error". No, it's not a syntax error.

Page 5/6

INCORRECT. "... you can declare a variable of type string (once you've included
the cstring standard header" .The header that declares the std::string type is
<string>. The header <cstring> is a different one.

*** Lecture 7 "Classes, part 2"

Page 7/3

INCORRECT. "[A constructor] initializes global variables". No, generally it does
not.

Page 7/6

INCORRECT. "A default constructor is a constructor that either has no
parameters, or if it has parameters, all the parameters have have default
values". The standard's definition is that a default constructor can be called
without arguments. E.g. 'T(...)' is a default constructor of class T.

Page 7/9

INCORRECT (FINE POINT). "If a copy constructor is not defined in a class, the
compiler itself defines one". In C++ there is a difference between "declared"
and "defined". "not defined" is incorrect (with practically significant
consequence) and should be replaced with "not declared".

Page 7/14

INCORRECT. "the assignment operator is not inherited". Assignment operators are
inherited, but are typically hidden by a programmer defined or automatically
generated derived class copy assignment operator.


*** Lecture 9 "File handling, operator overloading, and exceptions"

Page 9/2 "What does iostream.h contain?"

INCORRECT, 3 TIMES. <iostream.h> is not a standard C++ header. The corresponding
C++ header is <iostream>.

Page 9/5 and 9/6 "Function eof()-end of file"

CONFUSED. The example at the end is described both as a solution to a problem
(it's not), and as producing extraneous output (which it does).


*** Problem set 1 solutions

Page PS1/4 problem 9

EVIL "const int NUMBER_OF_VARIABLES = 2;" Reserve uppercase names for macros.

INCORRECT. "++x %= NUMBER_OF_VARIABLES" variable modified twice between sequence
points, Undefined Behavior.


*** Problem set 6 solutions

Page PS6/2 problem 1a
Page PS6/2 problem 1b

INCORRECT. The header <ctime> does not guaranteed declare time_t in the global
namespace. Should be std::time_t, or alternatively <time.h>.

EVIL. "getTime" for a member functin is a Java-ism.

Page PS6/7 problem 6

INCORRECT. The solution class Array fails to meet the "rule of three" by not
declaring an assignment operator, and will cause Undefined Behavior if Array
objects are ever assigned (due to double deletion).


*** Problem set 7 solutions

Page PS7/2 lab 7

INCORRECT. <conio.h> is not a standard C++ header.

Cheers,

- Alf (shocked)

--
blog at <url: http://alfps.wordpress.com>

red floyd

unread,
Sep 8, 2010, 3:36:42 PM9/8/10
to
On Sep 8, 12:15 pm, "Alf P. Steinbach /Usenet" <alf.p.steinbach

+use...@gmail.com> wrote:
> [This article is cross-posted to comp.lang.c++ and comp.programming]
>
> I was a bit shocked when I saw this a few days ago. I then used the MIT Open
> Courseware feedback option to inform them of the problems, where I explained
> things at about the same detail level as below, and was told that if a response
> was required it would be given within two business days. Well, either there's a
> holiday on in the MIT area, or MIT doesn't think this is problematic.
>

Just an FYI, Alf, not related to any of your comments (which seem
quite accurate to me):

Monday, 6 September, was a holiday (Labor Day) in the US. Don't know
if that helps with your timeline or not.

Pascal J. Bourguignon

unread,
Sep 8, 2010, 4:30:03 PM9/8/10
to
"Alf P. Steinbach /Usenet" <alf.p.stein...@gmail.com> writes:

> [This article is cross-posted to comp.lang.c++ and comp.programming]
>

> I was a bit shocked when I saw this a few days ago. [...]

> [...]
> - Alf (shocked)

Indeed, this is shocking.


--
__Pascal Bourguignon__ http://www.informatimago.com/

Christian Hackl

unread,
Sep 8, 2010, 6:33:51 PM9/8/10
to
Alf P. Steinbach /Usenet ha scritto:

> EVIL. "getTime" for a member functin is a Java-ism.

You mean because of camelCase or because of the verb?


(The lecture notes are quite bad, indeed.)


--
Christian Hackl
ha...@sbox.tugraz.at

Milano 2008/2009 -- L'Italia chiamň, sě!

Goran Pusic

unread,
Sep 9, 2010, 2:45:44 AM9/9/10
to
> Cheers,
>
> - Alf (shocked)

Hmmm... Not good, but I don't know about the "shocked" part.

The thing is, even though we're talking about fine academia (MIT _is_
considered a fine academia, right?), it's an introductory course in
the matter of practical programming (or so I guess), so precision is
kinda overrated. Even if course material was of a much higher quality,
students at this stage won't be able to neither appreciate or
understand finer points anyhow.

Also, if the course is actually there to teach students both C and C++
(which it seems to do)... Well, that doesn't help. It's just that the
material is enormous.

But hopefully if your post will help push MIT and other schools to
produce better material.

Education is not easy ( says a guy who escaped working in it ;-) ).

Goran.

Zeljko Vrba

unread,
Sep 9, 2010, 12:21:54 PM9/9/10
to
On 2010-09-09, Goran Pusic <gor...@cse-semaphore.com> wrote:
>
> The thing is, even though we're talking about fine academia (MIT _is_
> considered a fine academia, right?), it's an introductory course in
> the matter of practical programming (or so I guess), so precision is
> kinda overrated. Even if course material was of a much higher quality,
> students at this stage won't be able to neither appreciate or
> understand finer points anyhow.
>
Well, programming *is* very much about precision, i.e., precisely expressing
algorithmic ideas in a non-natural language (C++ in this case). If students
don't get that drilled into their subconciousness in an introductory course,
WHEN will they?

I agree that some percentage of students wouldn't be able to understand some of
the finer points. BUT, such materials send an implicit message that sloppyness
and/or cluelesness is "OK", which is not a good way of approaching programming.
Computers forgive neither.

(Even students less-knowledgeable in the start will eventually find out about
the mistakes through google or sites such as stackoverflow.)

Alf P. Steinbach /Usenet

unread,
Sep 9, 2010, 4:17:50 PM9/9/10
to
* Alf P. Steinbach /Usenet, on 08.09.2010 21:15:

>
> http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-096-introduction-to-c-january-iap-2009/
>
>
> 6.096 Introduction to C++
> As taught in: January IAP 2009
>
> Level:
> Undergraduate / Graduate
>
> Course Description
> This course is designed for undergraduate and graduate students in science,
> social science and engineering programs who need to learn fundamental
> programming skills quickly but not in great depth.

[snip list of errors]

I'm happy to report that the MIT course ...

[
http://ocw.mit.edu/courses/electrical-engineering-and-computer-science/6-088-introduction-to-c-memory-management-and-c-object-oriented-programming-january-iap-2010/

6.088 Introduction to C Memory Management and C++ Object-Oriented Programming
As taught in: January IAP 2010

Level:
Undergraduate
]

... appears to have far fewer errors.

In the first three lectures, covering basic C and memory management, a cursory
reading revealed no obvious technical errors. However, MIT's conversion to PDF
had removed some critical characters and lines in the code. E.g., "int* p, q;"
instead of "int *p, *q;" to declare two pointers (or, it may have been a lack of
understanding of the C syntax, but given the rest, and given a later white area
in the code I think it must have been the conversion to PDF that did it).

In the three remaining lectures, covering basic OO in C++, I saw only 1 obvious
source code error, declaring an initialized static member of 'float' type. This
was corrected in a later code sample so it seems the lecturer was discovering
the rules, writing the slides first and then actual code. Another hint in that
direction: the term "override" is incorrectly used to mean "redefine" in derived
class, and the lecturer went on about this (incorrect meaning of "override") for
several slides, so, not quite acquainted with C++.

For a course aimed at teaching memory management /and/ C++ OO, it would have
been nice if the student was shown how to use object oriented C++ memory
management, i.e. standard library containers and smart pointers.

Alas, instead also the C++ part (the three last lectures) is based on using raw
pointers and raw arrays, mentioning the standard library only at the very end.


Cheers,

- Alf (newfound calling, to evaluate MIT C++ courses :-) )

Joshua Maurice

unread,
Sep 9, 2010, 4:26:58 PM9/9/10
to
On Sep 9, 1:17 pm, "Alf P. Steinbach /Usenet" <alf.p.steinbach

+use...@gmail.com> wrote:
> Alas, instead also the C++ part (the three last lectures) is based on using raw
> pointers and raw arrays, mentioning the standard library only at the very end.

In MIT's defense, I think this is the way it should be. A good
programmer needs to understand the basics, and that includes raw
arrays. Only once one understands how to implement something simple
like vector should he actually use vector over raw arrays.

However, once he understands fully, hopefully he'll never use a raw
array again. (Wishful thinking.)

James Kanze

unread,
Sep 10, 2010, 4:24:10 AM9/10/10
to

NO! A beginning programmer, learning a language, has to, first
and foremost, understand the basic idioms of the language. In
C++, "raw" arrays are for special, advanced uses; the basic
idiom is std::vector, and that's what a beginning programmer
should learn first. (An experienced C++ will, of course, use
raw arrays as well as std::vector, depending on his needs.)

--
James Kanze

Christian Hackl

unread,
Sep 10, 2010, 6:06:14 AM9/10/10
to
James Kanze ha scritto:

> NO! A beginning programmer, learning a language, has to, first
> and foremost, understand the basic idioms of the language. In
> C++, "raw" arrays are for special, advanced uses; the basic
> idiom is std::vector, and that's what a beginning programmer
> should learn first.

Yes, exactly.

As I've said a few times before in this group, I was once personally
involved in a course which taught arrays/pointers first and the standard
containers as something very special.

It simply doesn't work, and it is also very frustrating for students;
once they finally manage to use dynamic arrays correctly in face of copy
constructors, assignment operators and exception safety in a slightly
more advanced program (which may well take an entire semester, because
after all this is not exactly easy stuff for a beginner, and at
university you usually have a lot of other courses, not only one about
C++), they cannot even take satisfaction in their new abilities, because
you have to tell them that all of this is "evil" and that if they just
write "std::vector<...>" they will get rid of all their hand-made memory
management code.

And of course, some will just stick to raw arrays because "they work"
and they "don't need special classes".


It's almost like teaching how to build your own virtual dispatch device
from scratch before introducing the virtual keyword... :)

Paul N

unread,
Sep 10, 2010, 7:34:15 AM9/10/10
to
On 9 Sep, 21:17, "Alf P. Steinbach /Usenet" <alf.p.steinbach
+use...@gmail.com> wrote:

(snip)

> In the three remaining lectures, covering basic OO in C++, I saw only 1 obvious
> source code error, declaring an initialized static member of 'float' type. This
> was corrected in a later code sample so it seems the lecturer was discovering
> the rules, writing the slides first and then actual code. Another hint in that
> direction: the term "override" is incorrectly used to mean "redefine" in derived
> class, and the lecturer went on about this (incorrect meaning of "override") for
> several slides, so, not quite acquainted with C++.

I thought that the term "override" meant that a function in a derived
class replaced a virtual function in the base class. This is what FAQ
20.1 seems to define it as. It also seems to be what you are saying
the course defines it as, and checking from the slides it does indeed
seem to be what the course defines it as. Could you clarify the
difference between what you think the course says and what you think
to be correct?

Thanks.
Paul.

Leigh Johnston

unread,
Sep 10, 2010, 7:53:14 AM9/10/10
to

"Paul N" <gw7...@aol.com> wrote in message
news:971359cc-d7f8-4b5b...@f26g2000vbm.googlegroups.com...

"Overriding a virtual function" is correct terminology whilst "Redefining a
virtual function" is also correct but less formal, Stroustrup uses both
terms in TC++PL. From the draft C++ standard:

"If a virtual member function vf is declared in a class Base and in a class
Derived, derived directly or indirectly
from Base, a member function vf with the same name, parameter-type-list
(8.3.5), cv-qualification, and refqualifier
(or absence of same) as Base::vf is declared, then Derived::vf is also
virtual (whether or not it is
so declared) and it overrides Base::vf."

/Leigh

/Leigh

Alf P. Steinbach /Usenet

unread,
Sep 10, 2010, 10:10:13 AM9/10/10
to
* Paul N, on 10.09.2010 13:34:

Hi Paul.

First, it's not a matter of personal opinion, as it seems you think.

C++ has an international standard, ISO/IEC 14882, that defines these things.

Essentially (I'm not sure how much of "virtual" you know about), when a class
Derived /overrides/ a method m from class Base, and you have a pointer p of type
Base* that points to an object originally created as Derived, then writing
p->m() invokes D::m.

That does not happen for a non-virtual method. When m is non-virtual the
expression p->m() invokes Base::m, because the known static type is Base. In
this case a/the redefinition of m in Derived is not an override.

The term "override" is loosely defined by the C++98 standard's §10.3/2, and then
used in many places in the standard to make the distinction I explained above.
"Override" applies only to virtual member functions. A non-virtual function can
be redefined in a derived class, and then the redefinition by default "hides"
the base class member.

For example, rules such as the standard's §10.3/5 about the return type of an
overriding function would be rather inconvenient, and meaningless, if "override"
refererred to non-virtual functions; it does not.

The MIT course, in contrast, incorrectly uses the word "override" about
non-virtual member functions (and goes on at length to define it that way),
which would make it impossible for a naïve student to understand parts of the
C++ standard such as the standard's §10.3/5, and corresponding concepts and
practical techniques such as C++ function result covariance.


Cheers & hth.,

- Alf

Pascal J. Bourguignon

unread,
Sep 10, 2010, 10:56:17 AM9/10/10
to
Christian Hackl <ha...@sbox.tugraz.at> writes:


So, you have to teach:

To make an array you write: std::vector<element_type> v(size);
To access to the vector you write: v.at(index)


Then you may mention that there is a low-level, unsafe feature whose syntax is:

To make an array you write: element_type v[size];
To access to the vector you write: v[index]

which obviously is much more practical to write, but that you shouldn't use.


Doesn't this just demonstrate that the whole language should be canned?

lucdanton

unread,
Sep 10, 2010, 11:07:19 AM9/10/10
to
On Sep 10, 4:56 pm, p...@informatimago.com (Pascal J. Bourguignon)
wrote:

std::vector is most equivalent to:

element_type *data = malloc(ELEMENT_COUNT * sizeof *data);
data[index];
free(data);

The most (IMO) equivalent to element_type data[ELEMENT_COUNT] is:

std::array<element_type, element_count> data;
data.at(index);

If it's C++03, there is std::tr1::array (which I hope does have a at
member).
If not, there is boost::array (or boost::tr1::array).
Or you can roll your own (IMO not a good exercise for an introductory
course however).

Christian Hackl

unread,
Sep 10, 2010, 11:22:34 AM9/10/10
to
On 10.09.2010 16:56, Pascal J. Bourguignon wrote:

> Christian Hackl <ha...@sbox.tugraz.at> writes:
>
> So, you have to teach:
>
> To make an array you write: std::vector<element_type> v(size);
> To access to the vector you write: v.at(index)

Actually, I'd teach v[index] first and later introduce v.at(index) as a
special way of accessing elements.

> Then you may mention that there is a low-level, unsafe feature whose syntax is:
>
> To make an array you write: element_type v[size];
> To access to the vector you write: v[index]

Frankly, I would not even mention raw arrays to the students until they
become more experienced with standard containers. If someone asks about
them, then I certainly would not fail to list all the things you
*cannot* do with them, e.g. adding elements, specifying the size
dynamically or returning them from a function.


And when it comes to dynamic low-level arrays, then the comparison is
very clear, anyway, thanks to all the manual memory management code you
have to cope with and which is reduced to zero when you use std::vector.

> which obviously is much more practical to write, but that you shouldn't use.

I don't think it's much more practical to write. It comes down to only
13 characters.

And you can actually search for "std::vector" in your code.

> Doesn't this just demonstrate that the whole language should be canned?

I fail to see how it demonstrates that.

Christian Hackl

unread,
Sep 10, 2010, 11:28:24 AM9/10/10
to
On 10.09.2010 17:07, lucdanton wrote:

> std::vector is most equivalent to:
>
> element_type *data = malloc(ELEMENT_COUNT * sizeof *data);
> data[index];
> free(data);

When compared with C. In C++, it would be:

element_type *data = new element_type[ELEMENT_COUNT];
data[index];
delete[] data;


Which is slightly less complex, but still bad enough for a beginner.
(And it introduces a new way of screwing up when you accidentally do
delete instead of delete[].)

Paul N

unread,
Sep 10, 2010, 12:14:01 PM9/10/10
to
On 10 Sep, 15:10, "Alf P. Steinbach /Usenet" <alf.p.steinbach

Thanks. Yes, I see your point now.

The course does first introduce a non-virtual function of the same
name and call this "overriding". It quite quickly starts explaining
how this can give unexpected results and shows how the cure is to make
the function virtual, but it fails to go back and say "actually we
were wrong to call this one overriding..."

Paul.

James Kanze

unread,
Sep 10, 2010, 1:46:07 PM9/10/10
to
On Sep 10, 3:56 pm, p...@informatimago.com (Pascal J. Bourguignon)
wrote:

> Christian Hackl <ha...@sbox.tugraz.at> writes:
> > James Kanze ha scritto:

[...]


> So, you have to teach:

> To make an array you write: std::vector<element_type> v(size);
> To access to the vector you write: v.at(index)

Why the at? That's an advanced feature, for the special (and
rare) cases where you want an exception on a bounds error,
instead of a crash.

> Then you may mention that there is a low-level, unsafe feature
> whose syntax is:

> To make an array you write: element_type v[size];
> To access to the vector you write: v[index]

> which obviously is much more practical to write, but that you
> shouldn't use.

Or should use when appropriate: it's not that C style arrays are
"low-level" (although they are), but that they have very
peculiar semantics.

> Doesn't this just demonstrate that the whole language should
> be canned?

Just because it's not perfect? C compatibility comes at
a price, but C++ probably wouldn't be anywhere near as widely
used without it.

--
James Kanze

Pascal J. Bourguignon

unread,
Sep 10, 2010, 1:54:05 PM9/10/10
to
James Kanze <james...@gmail.com> writes:

> On Sep 10, 3:56 pm, p...@informatimago.com (Pascal J. Bourguignon)
> wrote:
>> Christian Hackl <ha...@sbox.tugraz.at> writes:
>> > James Kanze ha scritto:
>
> [...]
>> So, you have to teach:
>
>> To make an array you write: std::vector<element_type> v(size);
>> To access to the vector you write: v.at(index)
>
> Why the at? That's an advanced feature, for the special (and
> rare) cases where you want an exception on a bounds error,
> instead of a crash.

LOL!

If you prefer a crash, why not use raw arrays and have out of bounds
crashes all the time?

>> Then you may mention that there is a low-level, unsafe feature
>> whose syntax is:
>
>> To make an array you write: element_type v[size];
>> To access to the vector you write: v[index]
>
>> which obviously is much more practical to write, but that you
>> shouldn't use.
>
> Or should use when appropriate: it's not that C style arrays are
> "low-level" (although they are), but that they have very
> peculiar semantics.
>
>> Doesn't this just demonstrate that the whole language should
>> be canned?
>
> Just because it's not perfect? C compatibility comes at
> a price, but C++ probably wouldn't be anywhere near as widely
> used without it.

And probably should be used much less than it is for it.

Kai-Uwe Bux

unread,
Sep 10, 2010, 2:10:06 PM9/10/10
to
Pascal J. Bourguignon wrote:

> James Kanze <james...@gmail.com> writes:
>
>> On Sep 10, 3:56 pm, p...@informatimago.com (Pascal J. Bourguignon)
>> wrote:
>>> Christian Hackl <ha...@sbox.tugraz.at> writes:
>>> > James Kanze ha scritto:
>>
>> [...]
>>> So, you have to teach:
>>
>>> To make an array you write: std::vector<element_type> v(size);
>>> To access to the vector you write: v.at(index)
>>
>> Why the at? That's an advanced feature, for the special (and
>> rare) cases where you want an exception on a bounds error,
>> instead of a crash.
>
> LOL!
>
> If you prefer a crash, why not use raw arrays and have out of bounds
> crashes all the time?

Of course, you use std::vector because with an array you are _less_ likely
to get a crash for out of bounds :-)

Formally, you have undefined behavior in both cases (vector and array).
However, with operator[] in std::vector, as a matter of quality of
implementation, you are likely to see

assert( arg < size() );

or something like that. So, for good implementations of vector::operator[]
you have a documented way to get a crash for out-of-bounds errors. With the
array, the compiler is less likely to generate bounds checking code.


As for operator[] vs at(): in cases where out-of-bounds errors are bugs, I
don't see what an exception buys you. Once you see that exception thrown,
you have to hunt down the bug and change the program anyway. Thus, during
the run of the program where the exception is thrown, you just discover that
the internal state of your program is inconsistent: different parts of the
program have different opinions on how long the vector is. The safest thing
would be to abort anyway before the inconsistency gets out of hand and your
program spends millions of dollars automatically buying stock options.


Best

Kai-Uwe Bux

Joshua Maurice

unread,
Sep 10, 2010, 2:11:56 PM9/10/10
to

I humbly disagree. I would rather that students have a firm grasp of
the language basics before using canned containers. I believe that a
firm grounding in simple imperative programming, such as assembly or
preferably simple C, is essential to being a good programmer. I
believe that you can use the standard library "better" if you
understand how the standard library is implemented. I see this problem
too often with Java programmers who do not understand basic complexity
theory and how their containers and standard libraries are
implemented, and consequently write very bad code.

Juha Nieminen

unread,
Sep 10, 2010, 2:26:25 PM9/10/10
to
In comp.lang.c++ Goran Pusic <gor...@cse-semaphore.com> wrote:
> The thing is, even though we're talking about fine academia (MIT _is_
> considered a fine academia, right?), it's an introductory course in
> the matter of practical programming (or so I guess), so precision is
> kinda overrated. Even if course material was of a much higher quality,
> students at this stage won't be able to neither appreciate or
> understand finer points anyhow.

Just because it's an introductory course doesn't excuse them from
giving incorrect information.

Juha Nieminen

unread,
Sep 10, 2010, 2:42:41 PM9/10/10
to
In comp.lang.c++ James Kanze <james...@gmail.com> wrote:
>> To make an array you write: std::vector<element_type> v(size);
>> To access to the vector you write: v.at(index)
>
> Why the at? That's an advanced feature, for the special (and
> rare) cases where you want an exception on a bounds error,
> instead of a crash.

Since when has the safer variant been the "advanced feature", while the
variant which causes UB when misused is the one suitable for beginners?

Leigh Johnston

unread,
Sep 10, 2010, 2:48:18 PM9/10/10
to

"Juha Nieminen" <nos...@thanks.invalid> wrote in message
news:4c8a7c21$0$12279$7b1e...@news.nbl.fi...

The variant which cause UB when misused is the preferred choice because the
goal is to write bug-free software which doesn't contain any misuse rather
than to write software containing bugs which need to be protected against.
operator[] will typically have an assert which can be detected in *debug*
mode. Answer: test and test again. :)

/Leigh

Leigh Johnston

unread,
Sep 10, 2010, 2:54:06 PM9/10/10
to
"Leigh Johnston" <le...@i42.co.uk> wrote in message
news:34qdnWQSi-Lp4BfR...@giganews.com...

> "Juha Nieminen" <nos...@thanks.invalid> wrote in message
> news:4c8a7c21$0$12279$7b1e...@news.nbl.fi...
>> Since when has the safer variant been the "advanced feature", while the
>> variant which causes UB when misused is the one suitable for beginners?
>
> The variant which cause UB when misused is the preferred choice because
> the goal is to write bug-free software which doesn't contain any misuse
> rather than to write software containing bugs which need to be protected
> against. operator[] will typically have an assert which can be detected in
> *debug* mode. Answer: test and test again. :)
>

That is a generalization of course as some domains are more critical than
others and require a higher degree of defensiveness.

/Leigh

Pascal J. Bourguignon

unread,
Sep 10, 2010, 3:12:32 PM9/10/10
to
Kai-Uwe Bux <jkher...@gmx.net> writes:

In some circumstances, you just cannot stop the program and wait for
programmers to correct the bug. Think about robots, or space probes.
Then you want to be able to catch the exceptions, and if you can reset
the vector to a bigger one and try again, or if you can just restart
the procedure and hopefully, real-time circumstances having changed,
avoid the bug, it would be much better than crashing a rocket or
hitting your grandma.

Kai-Uwe Bux

unread,
Sep 10, 2010, 3:16:15 PM9/10/10
to
Joshua Maurice wrote:

> On Sep 10, 1:24 am, James Kanze <james.ka...@gmail.com> wrote:
>> On Sep 9, 9:26 pm, Joshua Maurice <joshuamaur...@gmail.com> wrote:
>>
>> > On Sep 9, 1:17 pm, "Alf P. Steinbach /Usenet" <alf.p.steinbach
>> > +use...@gmail.com> wrote:
>> > > Alas, instead also the C++ part (the three last lectures) is
>> > > based on using raw pointers and raw arrays, mentioning the
>> > > standard library only at the very end.
>> > In MIT's defense, I think this is the way it should be. A good
>> > programmer needs to understand the basics, and that includes raw
>> > arrays. Only once one understands how to implement something simple
>> > like vector should he actually use vector over raw arrays.
>> > However, once he understands fully, hopefully he'll never use a raw
>> > array again. (Wishful thinking.)
>>
>> NO! A beginning programmer, learning a language, has to, first
>> and foremost, understand the basic idioms of the language. In
>> C++, "raw" arrays are for special, advanced uses; the basic
>> idiom is std::vector, and that's what a beginning programmer
>> should learn first. (An experienced C++ will, of course, use
>> raw arrays as well as std::vector, depending on his needs.)
>
> I humbly disagree. I would rather that students have a firm grasp of
> the language basics before using canned containers.

Dynamic allocation and deallocation (the perrils of using pointers) are by
no means the _basics_ of C++.

> I believe that a
> firm grounding in simple imperative programming, such as assembly or
> preferably simple C, is essential to being a good programmer. I
> believe that you can use the standard library "better" if you
> understand how the standard library is implemented.

True, but that does not mean that one should learn how the library is
implemented _before_ one learns how to use it. It only means that you will
learn how to use it better _while_ you learn how it is implemented.

> I see this problem
> too often with Java programmers who do not understand basic complexity
> theory and how their containers and standard libraries are
> implemented, and consequently write very bad code.

Before worrying about algorithmic complexity, I would worry about
correctness. Since along each path of control flow every new has to match
one and only one delete, dynamic allocation and deallocation introduces a
global state into the program that is very hard to reason about. Moreover,
dynamic m object management interacts very poorly with other language
features such as exceptions and templates: exceptions introduce surprising
paths into control flow. Learning "pointers" early runs the risk of students
developing habits that turn out bad only much later. E.g.:

template < typename T >
class example {
T * left;
T * right;
example & operator= ( example const & );
example ( example const & other );
public:
example ( T const & l, T const & r )
: left ( new T (l) )
, right ( new T (r) )
{}

~example ( void ) {
delete left;
delete right;
}
};

That looks fine, and making it exception safe will clutter the code. Since
it is flawed, however, arguing correctness is impossible or riddled with
many caveats. Using suitable smart pointers or other library components
helps to simplify the arguing considerably. As you cannot (and should not
even try to) teach all at once, I would argue that raw pointers have to wait
until the reasoning powers of the students are up for the task of handling
them correctly. Fortunately, the standard library allows one to do
interesting imperative programming problems way before that point.

Another exercise that exhibits the inherent difficulties of pointers is
this. Explain why the following is not just poor form but may indeed leak:

template < typename T >
class example {
T * data;
example & operator= ( example const & );
example ( example const & other );
public:
example ( T const & t ) {
data = new T;
*data = t;
}
~example ( void ) {
delete data;
}
};


Best

Kai-Uwe Bux

Kai-Uwe Bux

unread,
Sep 10, 2010, 3:30:29 PM9/10/10
to
Pascal J. Bourguignon wrote:

True, it depends on the circumstances: in a game, the player experience is
severely bad when it crashes, but a few frames where the physics is a little
off do not matter that much. On the other hand, I'd rather have a compiler
crash with "internal compiler error" than completing the run and producing
bogus code (which then will send me on a goose chase as I'd be hunting bugs
in _my_ code that are just figments of imagination).


Best

Kai-Uwe Bux

Christian Hackl

unread,
Sep 10, 2010, 3:35:14 PM9/10/10
to
Pascal J. Bourguignon ha scritto:

> In some circumstances, you just cannot stop the program and wait for
> programmers to correct the bug. Think about robots, or space probes.
> Then you want to be able to catch the exceptions, and if you can reset
> the vector to a bigger one and try again, or if you can just restart
> the procedure and hopefully, real-time circumstances having changed,
> avoid the bug, it would be much better than crashing a rocket or
> hitting your grandma.

What about embedding the application into a system which restarts it
automatically upon every crash, or which starts a backup application?

Joshua Maurice

unread,
Sep 10, 2010, 3:35:52 PM9/10/10
to

I think they're more basic than std::vector in terms of "first
principles". std::vector is implemented in terms of dynamic memory
allocation and deallocation, not the other way around. However, this
is rather pedantic, and doesn't really capture any of our main points.
See the rest of my reply.

> > I believe that a
> > firm grounding in simple imperative programming, such as assembly or
> > preferably simple C, is essential to being a good programmer. I
> > believe that you can use the standard library "better" if you
> > understand how the standard library is implemented.
>
> True, but that does not mean that one should learn how the library is
> implemented _before_ one learns how to use it. It only means that you will
> learn how to use it better _while_ you learn how it is implemented.

Perhaps. See below.

As long as we agree they should know how std::vector is implemented
eventually, I suppose it's a question of empirical fact as to which
order of learning is best.

As a guess purely on personal preference, I would prefer and I think I
would learn better if I learned how the internals of std::vector work
before hearing the explanation of the interface, contracts, and
guarantees of std::vector.

Also, if I was teaching an intro course for those who would take more
courses, I'm not sure I would focus as heavily on RAII and exception
safety as you do. Correctness of programs is important, but it's not
obvious to me that teaching someone with the use of fully correct
programs from the beginning is the best way to end up with someone who
writes fully correct programs at the end. As a (poor) analogy, I would
teach a student Newtonian physics before I taught them General
Relativity.

>   template < typename T >
>   class example {
>     T * data;
>     example & operator= ( example const & );
>     example ( example const & other );
>   public:
>     example ( T const & t ) {
>       data = new T;
>       *data = t;
>     }
>     ~example ( void ) {
>       delete data;
>     }
>   };

Indeed. For a sane program, "data = new T;" may succeed, but the
assignment "*data = t;" may throw, causing the constructor to not
finish, causing the lifetime of the object to never begin, causing the
standard invocation of destructor to never occur, causing the "data =
new T;" to never be freed.

However, I remain unconvinced that explaining this in an introduction
to C++ course is the best way to start teaching a new C++ programmer.

Joshua Maurice

unread,
Sep 10, 2010, 3:40:13 PM9/10/10
to
On Sep 10, 12:35 pm, Christian Hackl <ha...@sbox.tugraz.at> wrote:
> Pascal J. Bourguignon ha scritto:
>
> > In some circumstances, you just cannot stop the program and wait for
> > programmers to correct the bug.  Think about robots, or space probes.
> > Then you want to be able to catch the exceptions, and if you can reset
> > the vector to a bigger one and try again, or if you can just restart
> > the procedure and hopefully, real-time circumstances having changed,
> > avoid the bug, it would be much better than crashing a rocket or
> > hitting your grandma.
>
> What about embedding the application into a system which restarts it
> automatically upon every crash, or which starts a backup application?

And so it begins. I've seen this loop before, and I did not like it.

Hopefully my only addition to this oft repeated argument is that real
robust applications tend to be robust from "firewalling" or separating
the program into isolated units. In C++ on unix like systems, this is
commonly at the process level. For crazy embedded systems, I've heard
about mission critical applications being written by 3 independent
teams using 3 different algorithms, and there was a small election
holder system isolated from the 3, and it would act on the majority
vote. Any dissenting voter was reset.

C++ programs by their very nature are incredibly brittle and fragile.
One wrong line anywhere can cause the entire process to do very weird
things. To get robustness, isolate and have redundancies, backups,
transactions, failovers and automatic resets, etc.

Squeamizh

unread,
Sep 10, 2010, 3:41:31 PM9/10/10
to
On Sep 10, 10:54 am, p...@informatimago.com (Pascal J. Bourguignon)
wrote:

> James Kanze <james.ka...@gmail.com> writes:
> > On Sep 10, 3:56 pm, p...@informatimago.com (Pascal J. Bourguignon)
> > wrote:
> >> Christian Hackl <ha...@sbox.tugraz.at> writes:
> >> > James Kanze ha scritto:
>
> >     [...]
> >> So, you have to teach:
>
> >> To make an array you write:         std::vector<element_type>  v(size);
> >> To access to the vector you write:  v.at(index)
>
> > Why the at?  That's an advanced feature, for the special (and
> > rare) cases where you want an exception on a bounds error,
> > instead of a crash.
>
> LOL!  
>
> If you prefer a crash, why not use raw arrays and have out of bounds
> crashes all the time?

You seem to believe that the only advantage to using a std::vector
rather than a raw array is the at() member function.

Christian Hackl

unread,
Sep 10, 2010, 3:42:08 PM9/10/10
to
Juha Nieminen ha scritto:

For beginners it won't really make a difference. In practice, in both
cases their program will safely crash, and an explanation along the
lines of "for now, just keep in mind that formally the behaviour is not
defined when specifiying a wrong index, but for the purpose of this
exercise you may assume the program will crash" will suffice.


std::vector should (in my opinion) be taught before exceptions, so they
could not make proper use of at(), anyway. Teaching them operator[] has
the big plus of getting them used right away to the usual way of things.


--
Christian Hackl
ha...@sbox.tugraz.at

Milano 2008/2009 -- L'Italia chiamò, sì!

Juha Nieminen

unread,
Sep 10, 2010, 3:45:42 PM9/10/10
to

operator[] is not guaranteed to catch out-of-bounds accesses in any
mode, while at() is.

Pascal J. Bourguignon

unread,
Sep 10, 2010, 3:46:07 PM9/10/10
to
Kai-Uwe Bux <jkher...@gmx.net> writes:

> Before worrying about algorithmic complexity, I would worry about
> correctness.

Yes.

> Since along each path of control flow every new has to match
> one and only one delete, dynamic allocation and deallocation introduces a
> global state into the program that is very hard to reason about.

That's why you have to use a garbage collector.


> Moreover, dynamic m object management interacts very poorly with
> other language features such as exceptions and templates:
> exceptions introduce surprising paths into control flow.

Which is no problem for the garbage collector.

> Learning "pointers" early runs the risk of students developing
> habits that turn out bad only much later.

IMO, it would be better to teach assembler than C, up to the point of
having written a simple but complete program in assembler. Then
forget it completely for the rest of the cursus (apart of course in
the compiler course).


> Using suitable smart pointers or other library components
> helps to simplify the arguing considerably.

Still my point. If you have a language that you cannot use, but have
to use libraries built upon to make it usable, what's the point? Just
use a higher level language!

You can still do OO programming in assembler. Why don't we? Same here.

Juha Nieminen

unread,
Sep 10, 2010, 3:50:03 PM9/10/10
to
In comp.lang.c++ Christian Hackl <ha...@sbox.tugraz.at> wrote:
> Juha Nieminen ha scritto:
>
>> In comp.lang.c++ James Kanze <james...@gmail.com> wrote:
>>>> To make an array you write: std::vector<element_type> v(size);
>>>> To access to the vector you write: v.at(index)
>>> Why the at? That's an advanced feature, for the special (and
>>> rare) cases where you want an exception on a bounds error,
>>> instead of a crash.
>>
>> Since when has the safer variant been the "advanced feature", while the
>> variant which causes UB when misused is the one suitable for beginners?
>
> For beginners it won't really make a difference.

It makes a huge difference if the program tells the user "hey, you
accessed this vector out of boundaries, bad, bad" rather than behaving
erratically for unknown reasons.

> In practice, in both
> cases their program will safely crash

In which system does accessing a vector out of boundaries "safely crash"
for sure?

In most systems I know of it *might* crash, but it might also corrupt
some unrelated object/variable, causing erratic behavior which can be
really hard to debug.

Using at() avoids that.

Juha Nieminen

unread,
Sep 10, 2010, 3:53:32 PM9/10/10
to
Pascal J. Bourguignon <p...@informatimago.com> wrote:
> You can still do OO programming in assembler.

Not really. Unless you consider the "every variable is public" paradigm
a valid form OO programming.

Christian Hackl

unread,
Sep 10, 2010, 3:55:30 PM9/10/10
to
Joshua Maurice ha scritto:

> I humbly disagree. I would rather that students have a firm grasp of
> the language basics before using canned containers. I believe that a
> firm grounding in simple imperative programming, such as assembly or
> preferably simple C, is essential to being a good programmer. I
> believe that you can use the standard library "better" if you
> understand how the standard library is implemented. I see this problem
> too often with Java programmers who do not understand basic complexity
> theory and how their containers and standard libraries are
> implemented, and consequently write very bad code.

I think complexity theory and basic algorithms are best taught in a
separate course, without even focusing too much on computers. I'd want
students to be able to use just a pen and a piece of paper to show me
how a computer might sort a list of names or fill a hash table, or even
to name some non-computer example for something which takes O(n) steps.

This is orthogonal to the choice of teaching array first vs. teaching
std::vector first.


--
Christian Hackl
ha...@sbox.tugraz.at

Milano 2008/2009 -- L'Italia chiamň, sě!

Kai-Uwe Bux

unread,
Sep 10, 2010, 3:57:00 PM9/10/10
to
Pascal J. Bourguignon wrote:

One can _use_ C++. The above, however, are remarks about _teaching_ C++: a
context, you snipped away.

> You can still do OO programming in assembler.

No, I can't: the machines for which I once learned machine code are long
gone, and I did not keep up.

> Why don't we?

a) Assembler is a fast moving target.
b) Assembler is, from what I see from a distance, less convenient.
c) I don't do OO anyway :-)

> Same here.

I doubt it.


Best

Kai-Uwe Bux

Christian Hackl

unread,
Sep 10, 2010, 3:59:27 PM9/10/10
to
Juha Nieminen ha scritto:

> In which system does accessing a vector out of boundaries "safely crash"


> for sure?
>
> In most systems I know of it *might* crash, but it might also corrupt
> some unrelated object/variable, causing erratic behavior which can be
> really hard to debug.

I'm afraid I don't understand. How could it do anything like this if
there's an assertion leading to abort()?


Of course, if I was teaching this to students, I'd make sure that the
target platform/compiler of the course guaranteed a crash.

Kai-Uwe Bux

unread,
Sep 10, 2010, 4:12:28 PM9/10/10
to
Joshua Maurice wrote:

Very, very much agreed.

> As a guess purely on personal preference, I would prefer and I think I
> would learn better if I learned how the internals of std::vector work
> before hearing the explanation of the interface, contracts, and
> guarantees of std::vector.
>
> Also, if I was teaching an intro course for those who would take more
> courses, I'm not sure I would focus as heavily on RAII and exception
> safety as you do. Correctness of programs is important, but it's not
> obvious to me that teaching someone with the use of fully correct
> programs from the beginning is the best way to end up with someone who
> writes fully correct programs at the end. As a (poor) analogy, I would
> teach a student Newtonian physics before I taught them General
> Relativity.

The point is not to teach RAII early on. The point is to use the library and
teach safe idioms early so that reasoning becomes simpler. In effect, I
would introduce RAII probably in the context of pointers: new and delete
have to be matched in pairs (that mantra, I would strongly reinforce when
teaching pointers); the language guarantees that constructors and
destructors of a given object are paired along all paths of flow control.
So, let's new in the constructor and delete in the destructor and let the
guarantees of C++ take care of that part of reasoning.

However, as I would teach pointers somewhat late in the process, RAII would
also come somewhat late.

>> template < typename T >
>> class example {
>> T * data;
>> example & operator= ( example const & );
>> example ( example const & other );
>> public:
>> example ( T const & t ) {
>> data = new T;
>> *data = t;
>> }
>> ~example ( void ) {
>> delete data;
>> }
>> };
>
> Indeed. For a sane program, "data = new T;" may succeed, but the
> assignment "*data = t;" may throw, causing the constructor to not
> finish, causing the lifetime of the object to never begin, causing the
> standard invocation of destructor to never occur, causing the "data =
> new T;" to never be freed.
>
> However, I remain unconvinced that explaining this in an introduction
> to C++ course is the best way to start teaching a new C++ programmer.

There might be a slight misunderstanding: I would not even try to explain
that to a beginner. But when diving into pointers, I would feel the need to
explain something like that (maybe just in order to prevent bad coding
habits from being established). Hence, I would not explain pointers to
beginners and start elsewhere.

Here is a rough order that comes to mind:

* basic types: int, double, std::string.
* flow control.
* buildings complex types: classes and containers.
* standard library: iterators, algorithms, streams.
* function objects.
* exceptions and flow control via throw/catch.
* templates.
* smart pointers (e.g., tr1::shared_ptr<>, tr1::function<> )
* raw pointers and arrays.
* implementing all those nifty library features.

The elegance of pointers is that they can serve as a building block for so
many other things. But that power comes at the price of some huge (albeit
hidden) complexity.


Best

Kai-Uwe Bux

Christian Hackl

unread,
Sep 10, 2010, 4:15:51 PM9/10/10
to
Juha Nieminen ha scritto:

> operator[] is not guaranteed to catch out-of-bounds accesses in any
> mode, while at() is.

operator[] is guaranteed to catch out-of-bounds accesses in the MSVC
documentation of std::vector, when compiled with appropriate settings.
So if I settled on VC for my (imaginary :)) course, then my students
would get crashes.

Pascal J. Bourguignon

unread,
Sep 10, 2010, 4:20:36 PM9/10/10
to
Squeamizh <squ...@hotmail.com> writes:

Yes, to be informed when there's an out of bound condition. I want to
know when there's a bug in my programs.

Leigh Johnston

unread,
Sep 10, 2010, 4:33:17 PM9/10/10
to

"Juha Nieminen" <nos...@thanks.invalid> wrote in message

news:4c8a8ae6$0$12263$7b1e...@news.nbl.fi...

I never said it would, I said "operator[] will *typically* have an assert".

/Leigh

Balog Pal

unread,
Sep 10, 2010, 7:18:17 PM9/10/10
to
"Leigh Johnston" <le...@i42.co.uk>

>>> Since when has the safer variant been the "advanced feature", while the
>>> variant which causes UB when misused is the one suitable for beginners?
>>
>> The variant which cause UB when misused is the preferred choice because
>> the goal is to write bug-free software which doesn't contain any misuse
>> rather than to write software containing bugs which need to be protected
>> against. operator[] will typically have an assert which can be detected
>> in *debug* mode. Answer: test and test again. :)
>>
>
> That is a generalization of course as some domains are more critical than
> others and require a higher degree of defensiveness.

Yeah. And throwing an exception -- and continue execution in a faulting
state that was actually discovered -- is hardly a wise choice. Or a
defendable one. Unless certainly the program was written with *intent* of
out-of-bounds access (there are tricks to use endless loop, and let
exception terminate it), but in C++ those ways are normally on the DON'T
list.

Read Matthew Wilson's fine article in the recent Overload issue.

Les Cargill

unread,
Sep 10, 2010, 10:12:05 PM9/10/10
to
Pascal J. Bourguignon wrote:

> James Kanze<james...@gmail.com> writes:
>
>> On Sep 10, 3:56 pm, p...@informatimago.com (Pascal J. Bourguignon)
>> wrote:
>>> Christian Hackl<ha...@sbox.tugraz.at> writes:
>>>> James Kanze ha scritto:
>>
>> [...]
>>> So, you have to teach:
>>
>>> To make an array you write: std::vector<element_type> v(size);
>>> To access to the vector you write: v.at(index)
>>
>> Why the at? That's an advanced feature, for the special (and
>> rare) cases where you want an exception on a bounds error,
>> instead of a crash.
>
> LOL!
>
> If you prefer a crash, why not use raw arrays and have out of bounds
> crashes all the time?
>
>
>
>>> Then you may mention that there is a low-level, unsafe feature
>>> whose syntax is:
>>
>>> To make an array you write: element_type v[size];
>>> To access to the vector you write: v[index]
>>
>>> which obviously is much more practical to write, but that you
>>> shouldn't use.
>>
>> Or should use when appropriate: it's not that C style arrays are
>> "low-level" (although they are), but that they have very
>> peculiar semantics.
>>
>>> Doesn't this just demonstrate that the whole language should
>>> be canned?
>>
>> Just because it's not perfect? C compatibility comes at
>> a price, but C++ probably wouldn't be anywhere near as widely
>> used without it.
>
> And probably should be used much less than it is for it.
>


So why the "should"? Simply because it's harder on the student?

--
Les Cargill

Pascal J. Bourguignon

unread,
Sep 10, 2010, 11:39:05 PM9/10/10
to
Les Cargill <lcar...@cfl.rr.com> writes:

No, because it's less productive for the enterprises. Even if very
good programmers can be as productive as they always are with any
programming language, for the average programmers and most
applications, C++ is not a good choice. It's not for nothing that
Java took so much market share.

Les Cargill

unread,
Sep 11, 2010, 12:29:51 AM9/11/10
to
Pascal J. Bourguignon wrote:
> Les Cargill<lcar...@cfl.rr.com> writes:
>
>> Pascal J. Bourguignon wrote:
>>> James Kanze<james...@gmail.com> writes:
>>>> Just because it's not perfect? C compatibility comes at
>>>> a price, but C++ probably wouldn't be anywhere near as widely
>>>> used without it.
>>>
>>> And probably should be used much less than it is for it.
>>
>> So why the "should"? Simply because it's harder on the student?
>
> No, because it's less productive for the enterprises.

Sorry, I don't buy that. First, the measurement of
computer programmer productivity simply hasn't been done.
KLOC per fortnight? Bleh :) How... how do you do that? If
someone is deliberate enough to create no negative externalities
in the organization *at all* but doesn't meet the method of
measure in the organization, (s)he will not be considered effective -
even though an economist may be able to prove (s)he actually
*is*.

Second, when people have tried to do it, like in Fred Brooks'
book, the subject quickly turns to culture, not technology,
as the source of pain in software development.

Third, the subject "this is how arrays work in raw 'C'" is
probably a good thing for computer science students to know.
it's elegant.

Then again, I got stuck with a product which used a version of
std::map that just *failed* several years back, and I simply
ripped the failed thing out and put in something simple - in
'C' - because I could actually more-or-less-partial-prove correctness
of the thing in a test stand independent of the system - that worked.

I happened to have access to somebody who could support design
of the dataset to run against the thing.

That was intended as a stopgap to prove that the std::map was broken,
but it ended up shipped that way.

I spent three months (off and on) finding it, about four hours
replacing it. Okay, more than four hours to do the test stand, but
I included that in the three months:) The three months was because I
didn't believe it.

And I include that to illustrate just how bizarrely complex
a task measuring this sort of thing is. I don't have a real
hypothesis really, but the best people I have worked with
were those who had gone through an understanding of how
to do it with 'C', which I attribute ( informally ) to
simply having had to put up with the lack of higher level
construct support. it's rather like on a battlefield - once
you could do it *there*, you'd gained a lot of strategies for
dealing with bizarre defects that improved your ...
survivability in subsequent battles.

It's interesting, I've read a lot about it, and I don't think
we understand it very well. The rapidly declining set of people
who have even anecdotal data seems to emit less information
year by year...

> Even if very
> good programmers can be as productive as they always are with any
> programming language, for the average programmers and most
> applications, C++ is not a good choice.


That's an exellent statement of the standard explanation. The
thinking behind it should be readily evident as painful, I hope.

Projects designed like the Invasion of Normandy generally
turn out badly. Those are the ones where enough people are involved
to make "average" useful...


> It's not for nothing that
> Java took so much market share.
>

Java was the anti-MSC when MSC wasn't cool any more. It was
"at least it isn't Microsoft".

Java is fine, but Java deliverables seem to me to be among
the most defect-ridden I have used. I have to watch Eclipse
die at least once a week. Please note that this is yet another
uncomfortably unsupportable assertion. :) It's rather painful
when it happens. When an editor crashes, it's wrenching. But
that's an artifact of some sort of bias - it's not bad because
it's Java, it's just more likely that Java was used....

No single factor can explain any much of anything in this
field, I fear. Java is great as a defacto standard because
it is one, and that, as a measure of cultural utility, is
a good thing. Latin was an irredeemably convoluted
language, but it was Latin, and was the standard.

I've gotten stuck twice in professional capacity when big
piles o' Java went Bad, and was able in both cases to
pull a quick Tcl replacement ( at about 10:1 reduction
in time if not 100:1 ) to get us through a nightmare,
so I have to question the mores and cultural norms a bit.
None of those were cases where it was anything but *people's*
fault, but that was what I used to get out of a jam.

Tcl is what Sun threw under the bus to go after Microsoft
in the papers with Java. And my choice of that is just
about as path-dependent and arbitrary as anything else.

--
Les Cargill

Pascal J. Bourguignon

unread,
Sep 11, 2010, 1:06:11 AM9/11/10
to
Les Cargill <lcar...@cfl.rr.com> writes:

> Pascal J. Bourguignon wrote:
>> Les Cargill<lcar...@cfl.rr.com> writes:
>>
>>> Pascal J. Bourguignon wrote:
>>>> James Kanze<james...@gmail.com> writes:
>>>>> Just because it's not perfect? C compatibility comes at
>>>>> a price, but C++ probably wouldn't be anywhere near as widely
>>>>> used without it.
>>>>
>>>> And probably should be used much less than it is for it.
>>>
>>> So why the "should"? Simply because it's harder on the student?
>>
>> No, because it's less productive for the enterprises.
>
> Sorry, I don't buy that. First, the measurement of
> computer programmer productivity simply hasn't been done.
> KLOC per fortnight? Bleh :) How... how do you do that? If
> someone is deliberate enough to create no negative externalities
> in the organization *at all* but doesn't meet the method of
> measure in the organization, (s)he will not be considered effective -
> even though an economist may be able to prove (s)he actually
> *is*.

It has been done. Granted, perhaps on smaller projects. But still.
And C++ doesn't come out to any advantage.

http://web.cecs.pdx.edu/~apt/cs457_2005/hudak-jones.pdf
http://wwwipd.ira.uka.de/~prechelt/Biblio/jccpprtTR.pdf
http://www.codinghorror.com/blog/2005/08/are-all-programming-languages-the-same.html


> Second, when people have tried to do it, like in Fred Brooks'
> book, the subject quickly turns to culture, not technology,
> as the source of pain in software development.

Granted, there are other factors. That's not a reason to ignore the
programming language factor.


> Third, the subject "this is how arrays work in raw 'C'" is
> probably a good thing for computer science students to know.
> it's elegant.

Interesting to a geek, I won't deny it. But in the grand scheme of
things, it's irrelevant. Once you switch to automobiles with
combustion engine, whether your horse show has 8 holes or 9 holes
doesn't matter much.


> Then again, I got stuck with a product which used a version of
> std::map that just *failed* several years back, and I simply
> ripped the failed thing out and put in something simple - in
> 'C' - because I could actually more-or-less-partial-prove correctness
> of the thing in a test stand independent of the system - that worked.

Yes, that's a general problem with big libraries.

Juha Nieminen

unread,
Sep 11, 2010, 1:10:07 AM9/11/10
to
In comp.lang.c++ Christian Hackl <ha...@sbox.tugraz.at> wrote:
> Juha Nieminen ha scritto:
>
>> operator[] is not guaranteed to catch out-of-bounds accesses in any
>> mode, while at() is.
>
> operator[] is guaranteed to catch out-of-bounds accesses in the MSVC
> documentation of std::vector, when compiled with appropriate settings.
> So if I settled on VC for my (imaginary :)) course, then my students
> would get crashes.

I don't think teaching a specific compiler (and making the students rely
on features of that compiler) in a generic C++ course is the proper thing
to do.

You could *mention* that in VC, when compiling in debug mode, operator[]
will have boundary checks, but you should make it clear that this might not
be the case with all compilers, as it's not demanded by the standard. Then
you could say that the at() method is guaranteed to have boundary checks.

Juha Nieminen

unread,
Sep 11, 2010, 1:11:39 AM9/11/10
to
In comp.lang.c++ Christian Hackl <ha...@sbox.tugraz.at> wrote:
> Juha Nieminen ha scritto:
>
>> In which system does accessing a vector out of boundaries "safely crash"
>> for sure?
>>
>> In most systems I know of it *might* crash, but it might also corrupt
>> some unrelated object/variable, causing erratic behavior which can be
>> really hard to debug.
>
> I'm afraid I don't understand. How could it do anything like this if
> there's an assertion leading to abort()?

Could you show me the part of the C++ standard which guarantees that
std::vector::operator[] will abort() when it's accessed out of boundaries?

> Of course, if I was teaching this to students, I'd make sure that the
> target platform/compiler of the course guaranteed a crash.

I think you would be teaching them to rely on a feature which is not
guaranteed by the standard.

Les Cargill

unread,
Sep 11, 2010, 1:28:03 AM9/11/10
to

Those all cover degenerate, student-sized cases.


>> Second, when people have tried to do it, like in Fred Brooks'
>> book, the subject quickly turns to culture, not technology,
>> as the source of pain in software development.
>
> Granted, there are other factors. That's not a reason to ignore the
> programming language factor.
>
>

What data I have indicates that programming languages are a vanishing
factor.

>> Third, the subject "this is how arrays work in raw 'C'" is
>> probably a good thing for computer science students to know.
>> it's elegant.
>
> Interesting to a geek, I won't deny it. But in the grand scheme of
> things, it's irrelevant. Once you switch to automobiles with
> combustion engine, whether your horse show has 8 holes or 9 holes
> doesn't matter much.
>
>

You've changed domains in your analogy. Horses were clearly of
higher feasibility in many domains *up through the 1960s*.

These arguments always presume ( with a great deal of impatience,
I might add) the premise under which they are wrought.

Tch.

There are two issues:

1) Language infrastructure richness does not guarantee productivity
any more than feature richness of an appliances does.

2) Data on accountability factors in software production are
notoriously hard to gather and collate.

"It got more stuff" does not imply that what it produces is
of higher quality. Of course, there is always the jibe "quantity
is a quality all its own."

>> Then again, I got stuck with a product which used a version of
>> std::map that just *failed* several years back, and I simply
>> ripped the failed thing out and put in something simple - in
>> 'C' - because I could actually more-or-less-partial-prove correctness
>> of the thing in a test stand independent of the system - that worked.
>
> Yes, that's a general problem with big libraries.
>

It shouldn't be. And ignoring this puts people like me who
have a high degree of accountability for project accuracy in
a difficult spot.

But it's fashionable to wave the cigar and say "cest le guerre."

--
Les Cargill

kwikius

unread,
Sep 11, 2010, 4:37:14 AM9/11/10
to
On Sep 9, 9:17 pm, "Alf P. Steinbach /Usenet" <alf.p.steinbach
+use...@gmail.com> wrote:
> * Alf P. Steinbach /Usenet, on 08.09.2010 21:15:
>
>
>
> >http://ocw.mit.edu/courses/electrical-engineering-and-computer-scienc...
>
> > 6.096 Introduction to C++
> > As taught in: January IAP 2009
>
> > Level:
> > Undergraduate / Graduate
>
> > Course Description
> > This course is designed for undergraduate and graduate students in science,
> > social science and engineering programs who need to learn fundamental
> > programming skills quickly but not in great depth.
>
> [snip list of errors]
>
> I'm happy to report that the MIT course ...
>
> [http://ocw.mit.edu/courses/electrical-engineering-and-computer-scienc...
>
> 6.088 Introduction to C Memory Management and C++ Object-Oriented Programming
> As taught in: January IAP 2010
>
> Level:
> Undergraduate
> ]
>
> ... appears to have far fewer errors.

[...]

> - Alf (newfound calling, to evaluate MIT C++ courses :-) )

Hope you sent them a consulation fee + expenses + third home +
travel to exotic locations for essential conferences + contribution
towards essential 10 year sabbatical due to stress of paid 3 month
summer holiday breaks etc...


regards
Andy Little

Christian Hackl

unread,
Sep 11, 2010, 7:42:45 AM9/11/10
to
Juha Nieminen ha scritto:

>> I'm afraid I don't understand. How could it do anything like this if
>> there's an assertion leading to abort()?
>
> Could you show me the part of the C++ standard which guarantees that
> std::vector::operator[] will abort() when it's accessed out of boundaries?

"for now, just keep in mind that formally the behaviour is not


defined when specifiying a wrong index, but for the purpose of this
exercise you may assume the program will crash"

If a student still wants a more precise answer, then I'll point them to
the part of the compiler's documentation which states the guarantee.


>> Of course, if I was teaching this to students, I'd make sure that the
>> target platform/compiler of the course guaranteed a crash.
>
> I think you would be teaching them to rely on a feature which is not
> guaranteed by the standard.

In that sense, every programmer, even the most experienced one, relies
on a feature which is not guaranteed by using std::vector[].

Christian Hackl

unread,
Sep 11, 2010, 8:07:33 AM9/11/10
to
Juha Nieminen ha scritto:

> In comp.lang.c++ Christian Hackl <ha...@sbox.tugraz.at> wrote:
>> Juha Nieminen ha scritto:
>>
>>> operator[] is not guaranteed to catch out-of-bounds accesses in any
>>> mode, while at() is.
>> operator[] is guaranteed to catch out-of-bounds accesses in the MSVC
>> documentation of std::vector, when compiled with appropriate settings.
>> So if I settled on VC for my (imaginary :)) course, then my students
>> would get crashes.
>
> I don't think teaching a specific compiler (and making the students rely
> on features of that compiler) in a generic C++ course is the proper thing
> to do.

I would not teach a specific compiler.

But when you organise a programming course, you also need practical
exercises, and in order to do that correctly it is imperative that you
establish a target platform and compiler which is available to all
students throughout the semester and on which on all homework will be
tested.

Besides, no C++ compiler can (or should) be used sanely without custom
settings. It would be great if students could just type "g++ main.cpp"
or "cl main.cpp", but you have to tell them that they must also set
flags like -Wall or /Za before even being able to explain them their
exact meaning. By enforcing certain compiler options you will also
prohibit proprietary extensions.


> You could *mention* that in VC, when compiling in debug mode, operator[]
> will have boundary checks, but you should make it clear that this might not
> be the case with all compilers, as it's not demanded by the standard. Then
> you could say that the at() method is guaranteed to have boundary checks.

Yes.

It should certainly be taught to students that there is a difference
between what the standard says and how compilers implement it, and what
undefined behaviour is.


But that's what I said right from the beginning: I'd tell them that
formally you cannot count on operator[] detecting an error, but in the
context of the course and with a quality implementation used with
correct compiler settings it will work as expected, and it is also the
commonly preferred form in "real" code, not only in exercises at
university. (I'd probably tell them the other way round: with a bad
compiler or wrong settings operator[] might not work as expected.)


Needless to say that any out-of-bounds error, no matter if caused with
operator[] or at(), will lead to points being subtracted... :)

Bo Persson

unread,
Sep 11, 2010, 10:06:45 AM9/11/10
to

No, we just make sure that we don't use an out-of-bounds index. :-)


Bo Persson


kwikius

unread,
Sep 11, 2010, 10:22:48 AM9/11/10
to
On Sep 10, 6:46 pm, James Kanze <james.ka...@gmail.com> wrote:
> On Sep 10, 3:56 pm, p...@informatimago.com (Pascal J. Bourguignon)
> wrote:
>
> > Christian Hackl <ha...@sbox.tugraz.at> writes:
> > > James Kanze ha scritto:
>
> [...]
>
> > So, you have to teach:
> > To make an array you write: std::vector<element_type> v(size);
> > To access to the vector you write: v.at(index)
>
> Why the at? That's an advanced feature, for the special (and
> rare) cases where you want an exception on a bounds error,
> instead of a crash.

#include <vector>

int main)
{
std::vector<int> v(100U, 0);
v[100] = v[-1];
}

compiled without complaint ... didnt crash .. Great! Program must be
working .. ;-)

regards
Andy Little

Öö Tiib

unread,
Sep 11, 2010, 11:34:45 AM9/11/10
to
On 11 sept, 08:06, p...@informatimago.com (Pascal J. Bourguignon)
wrote:

> Les Cargill <lcarg...@cfl.rr.com> writes:
> > Pascal J. Bourguignon wrote:
> >> Les Cargill<lcarg...@cfl.rr.com>  writes:
>
> >>> Pascal J. Bourguignon wrote:

> >>>> James Kanze<james.ka...@gmail.com>   writes:
> >>>>> Just because it's not perfect?  C compatibility comes at
> >>>>> a price, but C++ probably wouldn't be anywhere near as widely
> >>>>> used without it.
>
> >>>> And probably should be used much less than it is for it.
>
> >>> So why the "should"? Simply because it's harder on the student?
>
> >> No, because it's less productive for the enterprises.
>
> > Sorry, I don't buy that. First, the measurement of
> > computer programmer productivity simply hasn't been done.
> > KLOC per fortnight? Bleh :) How... how do you do that? If
> > someone is deliberate enough to create no negative externalities
> > in the organization *at all* but doesn't meet the method of
> > measure in the organization, (s)he will not be considered effective -
> > even though an economist may be able to prove (s)he actually
> > *is*.
>
> It has been done.  Granted, perhaps on smaller projects.   But still.
> And C++ doesn't come out to any advantage.
>
> http://web.cecs.pdx.edu/~apt/cs457_2005/hudak-jones.pdf
> http://wwwipd.ira.uka.de/~prechelt/Biblio/jccpprtTR.pdf
> http://www.codinghorror.com/blog/2005/08/are-all-programming-language...

These are too small "projects". 1000 lines of code? 200 lines of
documentation? It is orders of magnitude smaller size than average
perhaps-good-for-something open source library people do at hobby-
time.

> > Second, when people have tried to do it, like in Fred Brooks'
> > book, the subject quickly turns to culture, not technology,
> > as the source of pain in software development.
>
> Granted, there are other factors.   That's not a reason to ignore the
> programming language factor.

There is certainly programming language factor with C++. It is complex
language and hard to learn. That does affect the availability of
specialists. Simpler to describe as *terrible* shortage of
specialists. India and China try to fill the cap hand-picking clever
guys from their two billions of population, but code that they produce
at moment is mostly crap and does not sell. That is no wonder when
even MIT teaches students in a way that Alf is shocked then it
probably is not much better in Peking.

> > Third, the subject "this is how arrays work in raw 'C'" is
> > probably a good thing for computer science students to know.
> > it's elegant.
>
> Interesting to a geek, I won't deny it.  But in the grand scheme of
> things, it's irrelevant.  Once you switch to automobiles with
> combustion engine, whether your horse show has 8 holes or 9 holes
> doesn't matter much.

Raw C is a language that has constantly been even more demanded than
java or C++. It is a joke to compare it with horses or other geek
hobby. With current smart-phone and other hand-held-anything computing
breaking to masses with no way back it keeps being demanded. You can
not run some sort of flash action script there since battery is empty
then in no time. C++ specialist is even better to have but expensive
to couch. I can bet that everybody who discarded C are currently
rapidly rediscovering it.

Christian Hackl

unread,
Sep 11, 2010, 11:37:13 AM9/11/10
to
kwikius ha scritto:

> #include <vector>
>
> int main)
> {
> std::vector<int> v(100U, 0);
> v[100] = v[-1];
> }
>
> compiled without complaint ... didnt crash .. Great! Program must be
> working .. ;-)

It does crash when you invoke the compiler with appropriate settings,
and you can also get a warning for the signed/unsigned conversion if you
wish so.


--
Christian Hackl
ha...@sbox.tugraz.at

Milano 2008/2009 -- L'Italia chiamň, sě!

Johannes Schaub (litb)

unread,
Sep 11, 2010, 11:53:14 AM9/11/10
to
Alf P. Steinbach /Usenet wrote:

> * Paul N, on 10.09.2010 13:34:
>> On 9 Sep, 21:17, "Alf P. Steinbach /Usenet"<alf.p.steinbach
>> +use...@gmail.com> wrote:
>>
>> (snip)
>>
>>> In the three remaining lectures, covering basic OO in C++, I saw only 1
>>> obvious source code error, declaring an initialized static member of
>>> 'float' type. This was corrected in a later code sample so it seems the
>>> lecturer was discovering the rules, writing the slides first and then
>>> actual code. Another hint in that direction: the term "override" is
>>> incorrectly used to mean "redefine" in derived class, and the lecturer
>>> went on about this (incorrect meaning of "override") for several slides,
>>> so, not quite acquainted with C++.
>>
>> I thought that the term "override" meant that a function in a derived
>> class replaced a virtual function in the base class. This is what FAQ
>> 20.1 seems to define it as. It also seems to be what you are saying
>> the course defines it as, and checking from the slides it does indeed
>> seem to be what the course defines it as. Could you clarify the
>> difference between what you think the course says and what you think
>> to be correct?
>
> Hi Paul.
>
> First, it's not a matter of personal opinion, as it seems you think.
>
> C++ has an international standard, ISO/IEC 14882, that defines these
> things.
>
> Essentially (I'm not sure how much of "virtual" you know about), when a
> class Derived /overrides/ a method m from class Base, and you have a
> pointer p of type Base* that points to an object originally created as
> Derived, then writing p->m() invokes D::m.
>
> That does not happen for a non-virtual method. When m is non-virtual the
> expression p->m() invokes Base::m, because the known static type is Base.
> In this case a/the redefinition of m in Derived is not an override.
>

Officially, it's called hiding. These two have different meanings.
Redefinition occurs for class names. In particular, for typedef names that
are declared in a scope where there is also a class declared. The class name
is redefined (instead if being hidden) by the typedef declaration to be then
a typedef name that refers to that class.

But if you have a base class and a derived class, the derived class defines
its own function, distinct from the base class function. Calling this
"redefinition" could cause confusion, I think. It does to me, at least.

Alf P. Steinbach /Usenet

unread,
Sep 11, 2010, 12:30:58 PM9/11/10
to
* Johannes Schaub (litb), on 11.09.2010 17:53:

Yes, I mentioned that in the very next paragraph (not quoted).


> These two have different meanings.
> Redefinition occurs for class names. In particular, for typedef names that
> are declared in a scope where there is also a class declared. The class name
> is redefined (instead if being hidden) by the typedef declaration to be then
> a typedef name that refers to that class.

No, "redefinition" is just an informal descriptive term. It means what it says,
no more or less. E.g. in the standard it's also used about redefining a
freestanding function, and in Stroustrup's TCPPPL 2nd ed. the index entry for
redefinition points to a discussion of redefinition of an enumeration value.


> But if you have a base class and a derived class, the derived class defines
> its own function, distinct from the base class function. Calling this
> "redefinition" could cause confusion, I think. It does to me, at least.

Hm. Well, it's a definition, and it defines a name to stand for something else
than it would have stood for without that definition, hence, redefinition. :-)


Cheers,

- Alf

--
blog at <url: http://alfps.wordpress.com>

Alf P. Steinbach /Usenet

unread,
Sep 11, 2010, 12:49:30 PM9/11/10
to
[Re-posted to comp.lang.c++ because Johannes had redirected follow-ups to
comp.lang.c++, thus removing my reply from comp.programming. Johannes: DON'T DO
THAT, and please don't snip a statement and replace with your own saying the
same, as if it hadn't been said. Those are not-nice discussion tactics.]

* Johannes Schaub (litb), on 11.09.2010 17:53:

Yes, I mentioned that in the very next paragraph (not quoted).


> These two have different meanings.
> Redefinition occurs for class names. In particular, for typedef names that
> are declared in a scope where there is also a class declared. The class name
> is redefined (instead if being hidden) by the typedef declaration to be then
> a typedef name that refers to that class.

No, "redefinition" is just an informal descriptive term. It means what it says,

no more or less. E.g. in the standard it's also used about redefining a
freestanding function, and in Stroustrup's TCPPPL 2nd ed. the index entry for
redefinition points to a discussion of redefinition of an enumeration value.

> But if you have a base class and a derived class, the derived class defines
> its own function, distinct from the base class function. Calling this
> "redefinition" could cause confusion, I think. It does to me, at least.

Hm. Well, it's a definition, and it defines a name to stand for something else

James Kanze

unread,
Sep 11, 2010, 3:54:55 PM9/11/10
to
On Sep 11, 6:06 am, p...@informatimago.com (Pascal J. Bourguignon)
wrote:

[...]


> > Sorry, I don't buy that. First, the measurement of
> > computer programmer productivity simply hasn't been
> > done. KLOC per fortnight? Bleh :) How... how do you do
> > that? If someone is deliberate enough to create no
> > negative externalities in the organization *at all* but
> > doesn't meet the method of measure in the organization,
> > (s)he will not be considered effective - even though an
> > economist may be able to prove (s)he actually *is*.

> It has been done. Granted, perhaps on smaller projects.
> But still. And C++ doesn't come out to any advantage.

> http://web.cecs.pdx.edu/~apt/cs457_2005/hudak-jones.pdfhttp://wwwipd.ira.uka.de/~prechelt/Biblio/jccpprtTR.pdfhttp://www.codinghorror.com/blog/2005/08/are-all-programming-language...

Very small projects. Small enough that scripting languages
have a definite edge. (Up to about 1000 LOC, I tend to use
AWK, rather than C++.) And none of the studies mentioned
study the maintainability of the results.

If the project is such that you can reasonable implement in
AWK (to choose a scripting language I know), then the AWK
implementation will probably be easier than one in C++. If
the project is large enough to require many separate
translation units (classes, etc.), then C++ or (I suspect)
Ada95 will come out better than Java (although Java does
work well for smaller projects, just above the size for
which typical scripting languages work).

--
James Kanze

James Kanze

unread,
Sep 11, 2010, 3:57:16 PM9/11/10
to
On Sep 10, 7:42 pm, Juha Nieminen <nos...@thanks.invalid> wrote:

> In comp.lang.c++ James Kanze <james.ka...@gmail.com> wrote:

> >> To make an array you write: std::vector<element_type> v(size);
> >> To access to the vector you write: v.at(index)

> > Why the at? That's an advanced feature, for the special
> > (and rare) cases where you want an exception on a bounds
> > error, instead of a crash.

> Since when has the safer variant been the "advanced


> feature", while the variant which causes UB when misused
> is the one suitable for beginners?

The "undefined behavior" should be a program crash on any
good implementation (at least one used by beginners). It is
with VC++ and with g++ (at least when invoked correctly).

--
James Kanze

James Kanze

unread,
Sep 11, 2010, 4:03:42 PM9/11/10
to
On Sep 10, 8:50 pm, Juha Nieminen <nos...@thanks.invalid> wrote:
> In comp.lang.c++ Christian Hackl <ha...@sbox.tugraz.at> wrote:
> > In practice, in both
> > cases their program will safely crash

> In which system does accessing a vector out of boundaries
> "safely crash" for sure?

Windows, when using VC++. Linux (and all of the other
Unices), when using g++.

> In most systems I know of it *might* crash, but it might
> also corrupt some unrelated object/variable, causing
> erratic behavior which can be really hard to debug.

You don't know Windows? Or g++? You're in a rather
exceptional situation, then. (OK, until about 2 years ago,
I'd never used either Windows or g++ professionally. But I
still knew they existed, and knew a little bit about them.)

> Using at() avoids that.

By causing an exception, which will cause more problems than
immediately crashing.

--
James Kanze

James Kanze

unread,
Sep 11, 2010, 4:05:41 PM9/11/10
to

> > [...]

> #include <vector>

It crashes with all of the compilers I use.

--
James Kanze

Johannes Schaub (litb)

unread,
Sep 11, 2010, 4:21:45 PM9/11/10
to
Alf P. Steinbach /Usenet wrote:

> [Re-posted to comp.lang.c++ because Johannes had redirected follow-ups to
> comp.lang.c++, thus removing my reply from comp.programming. Johannes:
> DON'T DO THAT, and please don't snip a statement and replace with your own
> saying the same, as if it hadn't been said. Those are not-nice discussion
> tactics.]
>

I did not mean to say that you did not notice that it's called hiding. I
just wanted to express my discomfort with that term, no more and no less :)

I'm sorry about the follow-ups thing, didn't notice my client does such a
thing by default. Hope you can forgive me once again? I'm all eager to fall
into nice discussions with you.

Johannes Schaub (litb)

unread,
Sep 11, 2010, 4:32:49 PM9/11/10
to

Looks like you are right. It says also "Unless redefined in the derived
class, members of a base class are also considered to be members of the
derived class." but I personally dislike this usage. "redefined" to
"redeclared" should have the same relationship as "defined" to "declared"
has. But in this case, it does not seem to be the case, because "redeclared"
has a very specific non-collegial meaning.

Alf P. Steinbach /Usenet

unread,
Sep 11, 2010, 4:35:03 PM9/11/10
to
* Johannes Schaub (litb), on 11.09.2010 22:21:

He he. I can't remember this happening earlier. So.

Jorgen Grahn

unread,
Sep 11, 2010, 4:45:37 PM9/11/10
to
On Fri, 2010-09-10, Joshua Maurice wrote:
...
> C++ programs by their very nature are incredibly brittle and fragile.

Unlike programs written in some other language ... ?

/Jorgen

--
// Jorgen Grahn <grahn@ Oo o. . .
\X/ snipabacken.se> O o .

Pascal J. Bourguignon

unread,
Sep 11, 2010, 4:54:17 PM9/11/10
to
Christian Hackl <ha...@sbox.tugraz.at> writes:

I find portability very valuable. If I were teacher, I would run
homeworks on as many different compilers and plateforms I could
(including 36-bit hardware, and EBCDIC systems), and I would multiply
the grade by the ratio of successful runs.

Jorgen Grahn

unread,
Sep 11, 2010, 5:03:35 PM9/11/10
to
["Followup-To:" header set to comp.lang.c++.]

On Sat, 2010-09-11, James Kanze wrote:
> On Sep 10, 8:50 pm, Juha Nieminen <nos...@thanks.invalid> wrote:
>> In comp.lang.c++ Christian Hackl <ha...@sbox.tugraz.at> wrote:
>> > In practice, in both
>> > cases their program will safely crash
>
>> In which system does accessing a vector out of boundaries
>> "safely crash" for sure?
>
> Windows, when using VC++. Linux (and all of the other
> Unices), when using g++.

What did you do to the real James Kanze?

salix:/tmp% cat foo.cc
#include <vector>
#include <iostream>

int main()
{
int bar[] = { 3, 3, 1, 8, 2 };
std::vector<int> foo(bar, bar+5);
for(unsigned i=0; i<10; ++i) {
std::cout << foo[i] << '\n';
}
return 0;
}
salix:/tmp% g++ -W -Wextra -pedantic -std=c++98 -o foo foo.cc
salix:/tmp% ./foo
3
3
1
8
2
0
135137
0
0
0
salix:/tmp%

Possibly I'm missing some context here, e.g. if you were talking about
special debug builds.

Jorgen Grahn

unread,
Sep 11, 2010, 5:23:52 PM9/11/10
to
["Followup-To:" header set to comp.lang.c++.]

On Sat, 2010-09-11, Christian Hackl wrote:

...


> But that's what I said right from the beginning: I'd tell them that
> formally you cannot count on operator[] detecting an error, but in the
> context of the course and with a quality implementation used with
> correct compiler settings it will work as expected,

I don't see how that helps the students. If they want such detection,
they can run their programs under valgrind or Purify (which they
should be taught to do anyway, to catch a dozen other common newbie
errors).

> and it is also the
> commonly preferred form in "real" code, not only in exercises at
> university.

I have never, ever used a bounds-checking std::vector<T>::operator[].
And I have never seen others use it, either. I rely on it to be as
fast as C array indexing.

I have heard rumors that such checks are enabled by default in the
Microsoft world ... but then I have also heard people complaining
"ooh, the standard containers are too slow for me, I must use raw
C-style arrays!" from the same world.

Christian Hackl

unread,
Sep 11, 2010, 5:30:44 PM9/11/10
to
Pascal J. Bourguignon ha scritto:

> I find portability very valuable. If I were teacher, I would run
> homeworks on as many different compilers and plateforms I could
> (including 36-bit hardware, and EBCDIC systems), and I would multiply
> the grade by the ratio of successful runs.

I think there's one problem with this approach in a beginner's course.

If students actually manage to write programs which compile and run fine
with all extensions disabled on Windows/VC or Linux/GCC, then it seem
very harsh to punish them if their code fails on some exotic machine,
moreso as the students themselves had not had the chance of testing
their code on those platforms before handing in the homework.


I would tell them that they must rely on primitive types having a
certain size or on other such things, but I would not want that to
affect their grades in a beginner's course. It is certainly a good thing
for more advanced courses, though, when you hand out assignments for
which students might actually be tempted to rely on specific hardware.


--
Christian Hackl
ha...@sbox.tugraz.at

Milano 2008/2009 -- L'Italia chiamň, sě!

Christian Hackl

unread,
Sep 11, 2010, 5:31:29 PM9/11/10
to
Pascal J. Bourguignon ha scritto:

> I find portability very valuable. If I were teacher, I would run


> homeworks on as many different compilers and plateforms I could
> (including 36-bit hardware, and EBCDIC systems), and I would multiply
> the grade by the ratio of successful runs.

I think there's one problem with this approach in a beginner's course.

If students actually manage to write programs which compile and run fine
with all extensions disabled on Windows/VC or Linux/GCC, then it seem
very harsh to punish them if their code fails on some exotic machine,
moreso as the students themselves had not had the chance of testing
their code on those platforms before handing in the homework.


I would tell them that they must not rely on primitive types having a

certain size or on other such things, but I would not want that to
affect their grades in a beginner's course. It is certainly a good thing
for more advanced courses, though, when you hand out assignments for
which students might actually be tempted to rely on specific hardware.


--
Christian Hackl
ha...@sbox.tugraz.at

Milano 2008/2009 -- L'Italia chiamň, sě!

Christian Hackl

unread,
Sep 11, 2010, 5:44:04 PM9/11/10
to
Jorgen Grahn ha scritto:

> ["Followup-To:" header set to comp.lang.c++.]
>
> On Sat, 2010-09-11, Christian Hackl wrote:
>
> ...
>> But that's what I said right from the beginning: I'd tell them that
>> formally you cannot count on operator[] detecting an error, but in the
>> context of the course and with a quality implementation used with
>> correct compiler settings it will work as expected,
>
> I don't see how that helps the students. If they want such detection,
> they can run their programs under valgrind or Purify (which they
> should be taught to do anyway, to catch a dozen other common newbie
> errors).

I don't understand... actually, this was just about operator[] vs. at(),
and in both cases, the resulting crash won't automatically point
students to the wrong line of code, if that's what you mean.

The crash first of foremost helps students in that they immediately see
that their code is wrong and must be fixed.

>> and it is also the
>> commonly preferred form in "real" code, not only in exercises at
>> university.
>
> I have never, ever used a bounds-checking std::vector<T>::operator[].
> And I have never seen others use it, either. I rely on it to be as
> fast as C array indexing.

I meant "preferred form" in the sense that it is preferred over at().

> I have heard rumors that such checks are enabled by default in the
> Microsoft world ... but then I have also heard people complaining
> "ooh, the standard containers are too slow for me, I must use raw
> C-style arrays!" from the same world.

This is indeed a rumor.

#include <vector>

int main()
{
std::vector<int> v;
v.reserve(100);
v[0] = 1;
}

If you compile this just with "cl test.cpp", then you probably won't get
a crash.

--
Christian Hackl
ha...@sbox.tugraz.at

Milano 2008/2009 -- L'Italia chiamň, sě!

Joshua Maurice

unread,
Sep 11, 2010, 5:49:48 PM9/11/10
to
On Sep 11, 1:45 pm, Jorgen Grahn <grahn+n...@snipabacken.se> wrote:
> On Fri, 2010-09-10, Joshua Maurice wrote:
>
> ...
>
> > C++ programs by their very nature are incredibly brittle and fragile.
>
> Unlike programs written in some other language ... ?

Yes. For example Java. If a library has a programming error in Java,
it is not heinous to throw an exception like it is in C++. Due to the
security guarantees of Java, a bug in the Java code can't corrupt
memory or do anything else particularly bad to the process, unlike a
bug in C++.

SG

unread,
Sep 11, 2010, 6:05:50 PM9/11/10
to
On 11 Sep., 23:03, Jorgen Grahn wrote:
> On Sat, 2010-09-11, James Kanze wrote:

Maybe.

Although students should know what guarantees the C++ standard makes
and what is compiler-specific, I think they should also be familiar
with the compiler's documentation they are working with. This includes
a possible debug mode the implementation may offer.

http://gcc.gnu.org/onlinedocs/libstdc++/manual/debug_mode.html

Cheers!
SG

Ian Collins

unread,
Sep 11, 2010, 7:19:14 PM9/11/10
to
On 09/12/10 09:49 AM, Joshua Maurice wrote:
> On Sep 11, 1:45 pm, Jorgen Grahn<grahn+n...@snipabacken.se> wrote:
>> On Fri, 2010-09-10, Joshua Maurice wrote:
>>
>> ...
>>
>>> C++ programs by their very nature are incredibly brittle and fragile.
>>
>> Unlike programs written in some other language ... ?
>
> Yes. For example Java. If a library has a programming error in Java,
> it is not heinous to throw an exception like it is in C++.

It isn't heinous to throw an exception in C++, it is perfectly acceptable.

> Due to the
> security guarantees of Java, a bug in the Java code can't corrupt
> memory or do anything else particularly bad to the process, unlike a
> bug in C++.

So throwing an exception and terminating isn't bad for the process?

--
Ian Collins

Öö Tiib

unread,
Sep 11, 2010, 7:48:26 PM9/11/10
to
On 12 sept, 00:03, Jorgen Grahn <grahn+n...@snipabacken.se> wrote:
> ["Followup-To:" header set to comp.lang.c++.]
>
> On Sat, 2010-09-11, James Kanze wrote:
> > On Sep 10, 8:50 pm, Juha Nieminen <nos...@thanks.invalid> wrote:
> >> In comp.lang.c++ Christian Hackl <ha...@sbox.tugraz.at> wrote:
> >> > In practice, in both
> >> > cases their program will safely crash
>
> >> In which system does accessing a vector out of boundaries
> >> "safely crash" for sure?
>
> > Windows, when using VC++.  Linux (and all of the other
> > Unices), when using g++.
>
> What did you do to the real James Kanze?

[...]

> Possibly I'm missing some context here, e.g. if you were talking about
> special debug builds.

The production builds are actually the "special" ones. Developers work
most of the time with tests, then debug builds then production builds.
Even the testers work more with debug builds. NDEBUG is best to keep
undefined in production builds as well (at least when compiling non-
performance critical parts). Then most asserts are checked on field
too and crash.

In similar way if it is not some performance critical container and
the implementation lets to mix the debug and release code then you can
use mostly debug containers even in production builds. On cases of
problems with performance about 9 times of 10 it is fault of wasteful
algorithms used and not bounds-checked containers.

Currently compilers can produce buffer overrun checking code even for
raw C buffers, and i think it is good to teach as first thing to
students how to turn every sort of checks on. It is wrong to turn such
things off before everything is tested.

Joshua Maurice

unread,
Sep 11, 2010, 9:53:14 PM9/11/10
to
On Sep 11, 4:19 pm, Ian Collins <ian-n...@hotmail.com> wrote:
> On 09/12/10 09:49 AM, Joshua Maurice wrote:
>
> > On Sep 11, 1:45 pm, Jorgen Grahn<grahn+n...@snipabacken.se>  wrote:
> >> On Fri, 2010-09-10, Joshua Maurice wrote:
>
> >> ...
>
> >>> C++ programs by their very nature are incredibly brittle and fragile.
>
> >> Unlike programs written in some other language ... ?
>
> > Yes. For example Java. If a library has a programming error in Java,
> > it is not heinous to throw an exception like it is in C++.
>
> It isn't heinous to throw an exception in C++, it is perfectly acceptable.

That's a difference of opinion. In C++, if a sanity check on a class
invariant is violated (which can only happen from a programming error,
or a cosmic ray, etc.), then my default action is to kill the process,
leaving a core dump or equivalent. If a sanity check is violated in
Java, then I /may/ throw an AssertionError, and let the caller decide
what to do.

> > Due to the
> > security guarantees of Java, a bug in the Java code can't corrupt
> > memory or do anything else particularly bad to the process, unlike a
> > bug in C++.
>
> So throwing an exception and terminating isn't bad for the process?

This is the oft repeated argument I spoke about earlier. Let me copy
and paste my earlier arguments.

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

On Sep 10, 12:40 pm, Joshua Maurice <joshuamaur...@gmail.com> wrote:
> Hopefully my only addition to this oft repeated argument is that real
> robust applications tend to be robust from "firewalling" or separating
> the program into isolated units. In C++ on unix like systems, this is
> commonly at the process level. For crazy embedded systems, I've heard
> about mission critical applications being written by 3 independent
> teams using 3 different algorithms, and there was a small election
> holder system isolated from the 3, and it would act on the majority
> vote. Any dissenting voter was reset.


>
> C++ programs by their very nature are incredibly brittle and fragile.

> One wrong line anywhere can cause the entire process to do very weird
> things. To get robustness, isolate and have redundancies, backups,
> transactions, failovers and automatic resets, etc.

You're welcome to disagree. Many people do. Preferably we won't rehash
the same arguments over and over again though.

Ian Collins

unread,
Sep 11, 2010, 10:05:13 PM9/11/10
to
On 09/12/10 01:53 PM, Joshua Maurice wrote:
> On Sep 11, 4:19 pm, Ian Collins<ian-n...@hotmail.com> wrote:
>> On 09/12/10 09:49 AM, Joshua Maurice wrote:
>>
>>> On Sep 11, 1:45 pm, Jorgen Grahn<grahn+n...@snipabacken.se> wrote:
>>>> On Fri, 2010-09-10, Joshua Maurice wrote:
>>
>>>> ...
>>
>>>>> C++ programs by their very nature are incredibly brittle and fragile.
>>
>>>> Unlike programs written in some other language ... ?
>>
>>> Yes. For example Java. If a library has a programming error in Java,
>>> it is not heinous to throw an exception like it is in C++.
>>
>> It isn't heinous to throw an exception in C++, it is perfectly acceptable..

>
> That's a difference of opinion. In C++, if a sanity check on a class
> invariant is violated (which can only happen from a programming error,
> or a cosmic ray, etc.), then my default action is to kill the process,
> leaving a core dump or equivalent. If a sanity check is violated in
> Java, then I /may/ throw an AssertionError, and let the caller decide
> what to do.

That is a design decision, not something imposed by the programming
language.

--
Ian Collins

Öö Tiib

unread,
Sep 11, 2010, 10:30:27 PM9/11/10
to

I would prefer to be treated with medical equipment that Joshua
Maurice has developed using C++. The one that he develops using java
might continue killing me despite it just moment ago realized that it
is insane.

Joshua Maurice

unread,
Sep 11, 2010, 11:00:03 PM9/11/10
to

I do not think that that is an accurate reflection of what I said. I
specifically stated that good fault tolerance in programs (of all
kinds and languages) is the result of fault isolation. In C++, this
can only really be accomplished at the process level because of the
way C++ is. However, Java has stricter security guarantees on
misbehaving programs, so you can achieve fault isolation inside of a
process in Java to a reasonable level. I would still use fault
isolation in the Java medical equipment just like the C++ medical
equipment, but the fault isolation may not be at the process level in
Java.

Joshua Maurice

unread,
Sep 11, 2010, 11:01:19 PM9/11/10
to

Yes. I agree. I hope that you're not trying to use that to dispute
anything I have said. Are you? In which case I am lost and humbly
request clarification please.

Message has been deleted

Joshua Maurice

unread,
Sep 11, 2010, 11:52:05 PM9/11/10
to
On Sep 11, 8:32 pm, Ian Collins <ian-n...@hotmail.com> wrote:
> I am doing my best to avoid getting drawn into yet another pointless
> language dick swinging contest.

I am trying to avoid that as well. That is not my intent.

> Sure a C++ program can operate at a lower level than a Java one, but not
> all (and probably very little) harm is done at the low level.  A
> misbehaving Java program can do just as much damage to it's data or
> peers as a misbehaving C++ program can.
>
> Most harm is done through poor design, not poor execution.

Ok. I guess we disagree on facts. I believe that a misbehaving Java
library cannot mess up the process as easily as a misbehaving C++
library. The C++ library could trash the entire memory subsystem with
a single bad line of code, which under certain coding styles is quite
easy to make. A race condition with the status quo or with the
upcoming standard. However, short of maliciousness, Java doesn't have
these problems. It's still possible that a bug in a library borks your
whole program, but the odds seem to be a lot less. It can't
inadvertently trash the memory subsystem, or cause a seg fault from a
race condition, etc.

Of course, it's all a matter of degree. Process boundaries are only
good to a degree. Separate physical hardware gives better fault
isolation than separate processes under Linux. In the end, as you say,
good design is required. After that, it all depends. Perhaps your
particulars require dumping core when your Java process hits a
programmer bug. I'm not in a position to comment on your design goals,
how good your fault isolation in the Java process is, etc. For
example, a misbehaving Java library could still make calls into other
libraries, which might trash the program. It's a judgment call as to
the proper response.

I just wanted to make the observations:
1- Fault tolerance requires fault isolation.
2- Generally one cannot reliably isolate faults inside of a C++
process. Fault isolation must be at the process level for C++.

After some replies, I made one final claim:
3- It's much easier to get more reliable fault isolation inside of a
single process in other languages, like Java, as opposed to C++.

And I definitely don't mean to get into a language dick waving
contest. I am just noting that fault isolation does not necessarily
need to be at the process level. it depends on the particulars.

Ian Collins

unread,
Sep 12, 2010, 1:10:51 AM9/12/10
to

I agree up to a point and I'd agree fully if we were comparing Java with
C. But C++ has mechanisms to enable objects to manage the access to and
lifetime of any dynamic memory they use. This levels the playing field
between C++ and Java applications. I's go further and say the ability
to manage any resource type with RAII tips the balance on favour of C++.

> Of course, it's all a matter of degree. Process boundaries are only
> good to a degree. Separate physical hardware gives better fault
> isolation than separate processes under Linux.

Why just under Linux?

> In the end, as you say,
> good design is required. After that, it all depends. Perhaps your
> particulars require dumping core when your Java process hits a
> programmer bug. I'm not in a position to comment on your design goals,
> how good your fault isolation in the Java process is, etc. For
> example, a misbehaving Java library could still make calls into other
> libraries, which might trash the program. It's a judgment call as to
> the proper response.

I seldom have cause to use Java, most of what I write is either close to
the metal, or close to the OS.

> I just wanted to make the observations:
> 1- Fault tolerance requires fault isolation.

Agreed.

> 2- Generally one cannot reliably isolate faults inside of a C++
> process. Fault isolation must be at the process level for C++.

Disagree. In my option C++ is no worse than Java in this regard. I
will concede that the developer has to take greater care in C++, but
where fault isolation isn't an issue, not having to care can have its
advantages!

> After some replies, I made one final claim:
> 3- It's much easier to get more reliable fault isolation inside of a
> single process in other languages, like Java, as opposed to C++.

I'd dispute "much". I'd also note that this greater protection from the
language has a cost: the reduction of the utility of the language.

One of the beauties of C++, its multi-paradigm nature means you can
choose to write code in the style of a number of other languages. I
have C++ code that's almost C (device drivers), code that could be
mistaken for Java (my XML libraries implement the Java DOM bindings) and
code that could be mistaken for PHP (my web application libraries). If
an application demands the fault isolation of Java, it can be just as
easily be written in a Java like subset of C++ as it can in Java.

--
Ian Collins

Joshua Maurice

unread,
Sep 12, 2010, 2:17:49 AM9/12/10
to
On Sep 11, 10:10 pm, Ian Collins <ian-n...@hotmail.com> wrote:
> On 09/12/10 03:52 PM, Joshua Maurice wrote:
> > On Sep 11, 8:32 pm, Ian Collins<ian-n...@hotmail.com>  wrote:
> >> Most harm is done through poor design, not poor execution.
>
> > Ok. I guess we disagree on facts. I believe that a misbehaving Java
> > library cannot mess up the process as easily as a misbehaving C++
> > library. The C++ library could trash the entire memory subsystem with
> > a single bad line of code, which under certain coding styles is quite
> > easy to make. A race condition with the status quo or with the
> > upcoming standard. However, short of maliciousness, Java doesn't have
> > these problems. It's still possible that a bug in a library borks your
> > whole program, but the odds seem to be a lot less. It can't
> > inadvertently trash the memory subsystem, or cause a seg fault from a
> > race condition, etc.
>
> I agree up to a point and I'd agree fully if we were comparing Java with
> C.  But C++ has mechanisms to enable objects to manage the access to and
> lifetime of any dynamic memory they use.  This levels the playing field
> between C++ and Java applications.  I's go further and say the ability
> to manage any resource type with RAII tips the balance on favour of C++.
>
> > Of course, it's all a matter of degree. Process boundaries are only
> > good to a degree. Separate physical hardware gives better fault
> > isolation than separate processes under Linux.
>
> Why just under Linux?

Sorry. I didn't want to say just "process" in that context as I
thought it was overly vague, so I picked a random operating system
which has good fault isolation between processes.

> > I just wanted to make the observations:
> > 1- Fault tolerance requires fault isolation.
>
> Agreed.
>
> > 2- Generally one cannot reliably isolate faults inside of a C++
> > process. Fault isolation must be at the process level for C++.
>
> Disagree.  In my option C++ is no worse than Java in this regard.  I
> will concede that the developer has to take greater care in C++, but
> where fault isolation isn't an issue, not having to care can have its
> advantages!

To be clear, I am not making any claims about Java at this point. I am
merely making the claim, to have a robust C++ product on a modern
desktop-like OS, you need to have the fault isolation at the process
level. No comparisons to Java. It's just a simple fact of making
robust C++ applications.

> > After some replies, I made one final claim:
> > 3- It's much easier to get more reliable fault isolation inside of a
> > single process in other languages, like Java, as opposed to C++.
>
> I'd dispute "much".  I'd also note that this greater protection from the
> language has a cost: the reduction of the utility of the language.
>
> One of the beauties of C++, its multi-paradigm nature means you can
> choose to write code in the style of a number of other languages.  I
> have C++ code that's almost C (device drivers), code that could be
> mistaken for Java (my XML libraries implement the Java DOM bindings) and
> code that could be mistaken for PHP (my web application libraries).  If
> an application demands the fault isolation of Java, it can be just as
> easily be written in a Java like subset of C++ as it can in Java.

I think it's not quote over empirical fact now. I don't think I'll be
able to convince you, but I don't think you fully get where I'm coming
from, so bear with me.

The question central in this discussion is what to do in the face of a
programming error when detected by a sanity check in the program. In a
"safer" language like Java, it is difficult and unlikely for a
programming error to break the memory subsystem, scramble random bits
of random objects, etc. In fact, Java has many guarantees on this
subject. However, yes, my argument rests on the assumption that the
JVM is correct, which isn't necessarily true, but it seems like a
reasonable enough assertion when compared to most desktop C++ programs
which have their correctness conditional on their operating system,
their "virtual" machine.

You just argued that with care, you can achieve the same benefits of
Java in C++. In some sense, I agree fully. However, my very premise, a
programmer error, contradicts "with great care by the programmer".
We're examining what should we do in the very real and common
occasions where the programmer "was not careful enough". In this case,
Java offers a lot more guarantees about process stability than C++
(conditioned on the correctness of the JVM).

When designing for robustness, one must anticipate that programmers
will not always be careful enough. Designing for robustness is
designing with the expectations of programmer bugs (and more). One
must have fault tolerance. One does this with redundancies, backups,
rollovers, transactions, etc., and most importantly fault isolation.
In this regard, C++ is very different than Java. (Not "better", as I
don't want to go there, just different.)

The very nature of Java, lack of pointer arithmetic, defined and
"sensible" outcomes from race conditions, defined and "sensible"
behavior on null pointer accesses, etc., aka all of its security
features, gives Java a higher degree of fault isolation intra-process
than C++.

Fault isolation by definition is how isolated are separate parts of
your application from faults in other parts of your application. In
Java, it's basically impossible to corrupt the bits of a local stack
object of someone's else's thread which did not have any escaped
references, but it's trivial for that to happen in C++ from a
programmer mistake.

kwikius

unread,
Sep 12, 2010, 5:00:13 AM9/12/10
to

my compiler it seems just uses unchecked offset from dynamically
allocated pointer... Its a freebie though from Gnu org or so... hmm..
maybe its just a load of rubbish.. Maybe I should have bought the VC+
+6 instead?

regards
Andy Little

Christian Hackl

unread,
Sep 12, 2010, 6:56:35 AM9/12/10
to
kwikius ha scritto:

> On Sep 11, 9:05 pm, James Kanze <james.ka...@gmail.com> wrote:
>> On Sep 11, 3:22 pm, kwikius <a...@servocomm.freeserve.co.uk> wrote:
>>
>>> #include <vector>
>>> int main)
>>> {
>>> std::vector<int> v(100U, 0);
>>> v[100] = v[-1];
>>> }
>>> compiled without complaint ... didnt crash .. Great!
>>> Program must be working .. ;-)
>> It crashes with all of the compilers I use.
>

> my compiler it seems just uses unchecked offset from dynamically
> allocated pointer... Its a freebie though from Gnu org or so... hmm..
> maybe its just a load of rubbish.. Maybe I should have bought the VC+
> +6 instead?

You should by no means do that when you can even download VC++ 2010 for
free at Microsoft's website.


Or you check your current compiler's documentation for checked access.

Bo Persson

unread,
Sep 12, 2010, 7:51:58 AM9/12/10
to
Christian Hackl wrote:
> kwikius ha scritto:
>
>> On Sep 11, 9:05 pm, James Kanze <james.ka...@gmail.com> wrote:
>>> On Sep 11, 3:22 pm, kwikius <a...@servocomm.freeserve.co.uk>
>>> wrote:
>>>> #include <vector>
>>>> int main)
>>>> {
>>>> std::vector<int> v(100U, 0);
>>>> v[100] = v[-1];
>>>> }
>>>> compiled without complaint ... didnt crash .. Great!
>>>> Program must be working .. ;-)
>>> It crashes with all of the compilers I use.
>>
>> my compiler it seems just uses unchecked offset from dynamically
>> allocated pointer... Its a freebie though from Gnu org or so...
>> hmm.. maybe its just a load of rubbish.. Maybe I should have
>> bought the VC+ +6 instead?
>
> You should by no means do that when you can even download VC++ 2010
> for free at Microsoft's website.
>

Which even warns at compile time that using -1 for an unsigned
argument might not be a good idea. :-)


Bo Persson


kwikius

unread,
Sep 12, 2010, 8:08:04 AM9/12/10
to
On Sep 12, 11:56 am, Christian Hackl <ha...@sbox.tugraz.at> wrote:
> kwikius ha scritto:
>
>
>
> > On Sep 11, 9:05 pm, James Kanze <james.ka...@gmail.com> wrote:
> >> On Sep 11, 3:22 pm, kwikius <a...@servocomm.freeserve.co.uk> wrote:
>
> >>> #include <vector>
> >>> int main)
> >>> {
> >>>   std::vector<int> v(100U, 0);
> >>>   v[100] = v[-1];
> >>> }
> >>> compiled without complaint  ... didnt crash .. Great!
> >>> Program must be working  .. ;-)
> >> It crashes with all of the compilers I use.
>
> > my compiler it seems just uses unchecked offset from dynamically
> > allocated pointer... Its a freebie though from Gnu org or so... hmm..
> > maybe its just a load of rubbish.. Maybe I should have bought the VC+
> > +6 instead?
>
> You should by no means do that when you can even download VC++ 2010 for
> free at Microsoft's website.

Great! Does it work in Linux ?

regards
Andy Little

Lie Ryan

unread,
Sep 12, 2010, 8:43:31 AM9/12/10
to

Rather than having the student's code being able to compile for all
those exotic machines; I'd rather like to see the teacher's code compile
on all those exotic machines first before subjecting the student's code
to do the same.

I have been in a university course where I have to debug the teacher's
code (which was going to be used for assignment) that doesn't run
correctly on a Linux machine because the code relies on rand() always
returning a number that fits a 16-bit integers (which crippled platform
does that in this age of 32-bit and 64-bit CPU?); it doesn't help that
the code raises hundreds of compiler warnings when compiled with -Wall
-pedantic and how it liberally mixes tabs and spaces (worst: the tab
width setting for each file is different). Even worst is how they write
assignment specs almost like: "write a C++ program that behaves like
this .exe program".

Jorgen Grahn

unread,
Sep 12, 2010, 10:20:42 AM9/12/10
to
On Sat, 2010-09-11, Öö Tiib wrote:
> On 12 sept, 00:03, Jorgen Grahn <grahn+n...@snipabacken.se> wrote:
>> ["Followup-To:" header set to comp.lang.c++.]
>>
>> On Sat, 2010-09-11, James Kanze wrote:
>> > On Sep 10, 8:50 pm, Juha Nieminen <nos...@thanks.invalid> wrote:
>> >> In comp.lang.c++ Christian Hackl <ha...@sbox.tugraz.at> wrote:
>> >> > In practice, in both
>> >> > cases their program will safely crash
>>
>> >> In which system does accessing a vector out of boundaries
>> >> "safely crash" for sure?
>>
>> > Windows, when using VC++.  Linux (and all of the other
>> > Unices), when using g++.
>>
>> What did you do to the real James Kanze?
>
> [...]
>
>> Possibly I'm missing some context here, e.g. if you were talking about
>> special debug builds.
>
> The production builds are actually the "special" ones. Developers work
> most of the time with tests, then debug builds then production builds.
> Even the testers work more with debug builds.

You're changing the subject here: I just wanted to disproved the
statement "accessing a vector out of boundaries will 'safely crash'
for sure". Anyway:

I think I mentioned it elsewhere, but I've never used the debug
versions of the containers, and I've never seen them used in projects.
My guess is that they're not used nearly as often as you suggest.

> NDEBUG is best to keep
> undefined in production builds as well (at least when compiling non-
> performance critical parts). Then most asserts are checked on field
> too and crash.

NDEBUG and assert() on the other hand are often used in my world,
but that's a separate issue.

Jorgen Grahn

unread,
Sep 12, 2010, 10:30:03 AM9/12/10
to
On Sun, 2010-09-12, Joshua Maurice wrote:
...

> This is the oft repeated argument I spoke about earlier. Let me copy
> and paste my earlier arguments.
>
> http://groups.google.com/group/comp.lang.c++/msg/d18ffde8d09d4f4d
>
> On Sep 10, 12:40 pm, Joshua Maurice <joshuamaur...@gmail.com> wrote:
>> Hopefully my only addition to this oft repeated argument is that real
>> robust applications tend to be robust from "firewalling" or separating
>> the program into isolated units. In C++ on unix like systems, this is
>> commonly at the process level. For crazy embedded systems, I've heard
>> about mission critical applications being written by 3 independent
>> teams using 3 different algorithms, and there was a small election
>> holder system isolated from the 3, and it would act on the majority
>> vote. Any dissenting voter was reset.
>>
>> C++ programs by their very nature are incredibly brittle and fragile.
>> One wrong line anywhere can cause the entire process to do very weird
>> things. To get robustness, isolate and have redundancies, backups,
>> transactions, failovers and automatic resets, etc.
>
> You're welcome to disagree. Many people do. Preferably we won't rehash
> the same arguments over and over again though.

It would help if you wouldn't use insulting phrases like "incredibly
brittle and fragile" about C++ on comp.lang.c++. If you had something
more important to say (which I think you probably did) you could have
phrased that differently. Something like "unlike e.g. Java you cannot
sandbox C or C++ code without process borders", or whatever the right
phrasing is.

Daniel

unread,
Sep 12, 2010, 10:48:11 AM9/12/10
to
On Sep 11, 3:54 pm, James Kanze <james.ka...@gmail.com> wrote:
>
> Very small projects.  Small enough that scripting languages
> have a definite edge.  (Up to about 1000 LOC, I tend to use
> AWK, rather than C++.)  And none of the studies mentioned
> study the maintainability of the results.

perl is pretty good for a lot of tasks - complex reporting, data
extracts, etc. A comparable Java/C++ would probably have 10x/40x more
lines of code respectively.
>
>(although Java does
> work well for smaller projects, just above the size for
> which typical scripting languages work).
>
Interesting. James, everyone respects your programming skills, but
your writings on Java are frankly nuts :-) Look at the open source
world, there are tons of very highly regarded Java projects,
particularly in the areas of XML processing, data processing web
servers, etc. Some are collaborative, some are single author. A good
example of a widely used single author tool is Saxon maintained by
Michael Kay. I checked an older version, and it has about 1000
classes, organized into packages, typically from 100-200 loc, although
some are larger. I maintain a rather less widely used Java open
source tool, which has about 2800 classes, organized into packages,
which seems to be a workable size for one person to maintain. My
experience is that scripting languages won't work for this size of
projects.

There are C++ counterparts for some of the Java projects, e.g. Apache
xerces and xalan C++ versions, but they tend to have fewer features,
larger code bases, weird syntax, custom classes for things like
strings, and the consequent need to spend a day on google to figure
out how it all works.

-- Daniel

Marc

unread,
Sep 12, 2010, 12:31:39 PM9/12/10
to
kwikius wrote:

> On Sep 11, 9:05 pm, James Kanze <james.ka...@gmail.com> wrote:
>> On Sep 11, 3:22 pm, kwikius <a...@servocomm.freeserve.co.uk> wrote:
>> > #include <vector>
>> > int main)
>> > {
>> >   std::vector<int> v(100U, 0);
>> >   v[100] = v[-1];
>> > }
>> > compiled without complaint  ... didnt crash .. Great!
>> > Program must be working  .. ;-)
>>
>> It crashes with all of the compilers I use.

That must be a very specialized list.

> my compiler it seems just uses unchecked offset from dynamically
> allocated pointer... Its a freebie though from Gnu org or so... hmm..
> maybe its just a load of rubbish.. Maybe I should have bought the VC+
> +6 instead?

http://gcc.gnu.org/onlinedocs/libstdc++/manual/debug_mode.html

Keith H Duggar

unread,
Sep 12, 2010, 1:54:07 PM9/12/10
to
On Sep 12, 10:48 am, Daniel <danielapar...@gmail.com> wrote:
> On Sep 11, 3:54 pm, James Kanze <james.ka...@gmail.com> wrote:
> > Very small projects.  Small enough that scripting languages
> > have a definite edge.  (Up to about 1000 LOC, I tend to use
> > AWK, rather than C++.)  And none of the studies mentioned
> > study the maintainability of the results.
>
> perl is pretty good for a lot of tasks - complex reporting, data
> extracts, etc.  A comparable Java/C++ would probably have 10x/40x more
> lines of code respectively.

Oh my, the nonsense people pull from thin air. On multiple occasions
I've had to convert Perl to C++ and the C++ has /never/ been more than
3x the lines. The range is 1x to 3x. Your 40x claim is nearly comical
(and would be but for the poor noobs that will believe your nonsense).

KHD

It is loading more messages.
0 new messages