Journal Articles

CVu Journal Vol 11, #2 - Feb 1999 + Letters to the Editor
Browse in : All > Journals > CVu > 112 (20)
All > Journal Columns > LettersEditor (132)
Any of these categories - All of these categories

Note: when you create a new publication type, the articles module will automatically use the templates user-display-[publicationtype].xt and user-summary-[publicationtype].xt. If those templates do not exist when you try to preview or display a new article, you'll get this warning :-) Please place your own templates in themes/yourtheme/modules/articles . The templates will get the extension .xt there.

Title: Questions & Answers

Author: Administrator

Date: 07 February 1999 13:15:29 +00:00 or Sun, 07 February 1999 13:15:29 +00:00

Summary: 

Body: 

Questions from Tony Houghton

I read Harpist's "Getting Started" article, because even programmers who consider themselves experienced can learn from that sort of thing. I noticed what appears to be a bug. In the line which first appears about a third of the way down the first column on p.31 and is repeated nearer the bottom, surely:

++counters[tolower(data_string)];

should be:

++counters[tolower(data_string[iter])]; 

But what I'm really writing for is because I've got a query about something he said in this article and another one about something you said in a book review. Just below that problem bit of code the Harpist said, "I like that simple use of strlen()...." Does he mean he prefers:

for (iter = 0; iter < strlen(data_string); ++iter)

to:

int length = strlen(data_string);
for (iter = 0; iter < length; ++iter)

I thought the former was supposed to be anathema to anyone with half a mind to efficiency.

He also mentions he prefers the pre-increment to post-increment. Good.

I also tend to use pre-increment for the same reason (post-increment can be less efficient for C++ classes) and wondered if I was going against idiom because most C programmers seem to use post-. so it's nice to know someone of the Harpist's calibre considers I'm doing something right.

On to your review of "Practical C Programming". On p.44 you point out the line:

const char DATA_FILE[] = "numbers.dat";

Your first comment is "why a const char, rather than a const char * or plain char?" I can see the rest of what's wrong with that line, but if I did want a hard-coded file name I'd tend to write:

static const char data_file[] = "numbers.dat";

(or perhaps use the name DataFile if I wanted to use partial caps to indicate a non-macro constant). So what's wrong with const char[]?

Answers

From the Harpist.

You are, of course, entirely correct in that I forgot the index (and the second one was just cut and pasting from the first. Thanks for spotting it.

In the second case, I agree that it might be better coding to haul the calculation of the length out of the loop (I sort of assume that compilers will do that for me ). My comment was simply that I get tired of seeing students hand-coding things that are already in the Standard C Library. I place great emphasis on getting novices to use what is already available while reserving their efforts to using it sensibly.

The Harpist also commented on pre-incrementing but I snipped it, see below.

From Francis

Let me expand a little on my brief comment quoted above.

There seems to me that there are two sensible alternatives. Either for reasons best known to the code writer the program has the file name hard coded into the executable or the file name is being provided as a default value that maybe over-ridden at execution time. Let me take the two choices separately.

Choice 1.

In this case you are providing a string literal and do not intend it to be changed. So why provide it and then copy it into an array that has been declared as non-modifiable? String literals are semantically non-modifiable in C89 (in other words they behave as arrays of const char) and are actually const qualified in C++. If you want to reference a string literal it seems to me to be much better style to use a const char *. This also allows the value to be used in several translation units. In those where I do not provide the definition I can write:

extern char const* data_file;

Note that I must not ever write:

extern char data_file[];

unless it was defined as an array. Declarations and definitions of global variables must agree exactly, an array in one translation unit and a pointer in another will not work.

Of course, in the context, I think any variation on this choice is silly. However the point I was making is that having elected to have a global const variable it makes no sense to turn it into an array with the extra potential for getting it wrong as well as possibly getting an extra copy.

Choice 2.

If the intention had been simply to provide a default file name, I would have preferred one that resulted in a maximum size array (for a file name).

I think that providing a default file name is not unreasonable, and then you do have to provide an array of char (but not const qualified, and have to be careful of the declarations and definition matching) into which a user-selected alternative can be written at execution time.

From Allan Newton

Question 1

Reading C Vu 11.1 I was struck by the Harpist's comment (Getting Started) to the effect that pre incrementing is better than post incrementing in a loop counter i.e. this

for ( ctr = 0 ; ctr < limit ; ++ctr )

better than

for ( ctr = 0 ; ctr < limit ; ctr++ )

I have seen similar comments in other places but usually without explanation or justification.

Could the Harpist or some other guru educate me please.

As the for loop is probably my most commonly used structure statement and I tend to post increment I would like to know what I am doing wrong and what benefits would accrue if I changed my style.

Question 2

Incidentally since I often loop over the same structure would it be good or bad to adopt something on these lines:

#define LOOPSTART
    for ( unsigned long int ctr = 0 ; ctr != limit; ++ctr) {
#define LOOPEND
       }

Then I merely write everywhere

LOOPSTART

do something incredibly useful

LOOPEND

A relevant comment is that I find I make more typo's in what I call "housekeeping" code like structure controls etc. than I do in "physics" code. Interestingly my practice of trying to be consistent with naming, layout and format is actually a hindrance at tracking down the errors because of the well known proof readers problem of reading what you expect to see. Having said that my consistency approach surely reduces the number of errors by orders of magnitude and will aid anyone else reading my code (a pretty rare event)

Question 3

As a total aside with the possibility of help and exchanges like this why are not more of our members who work alone not fighting to get onto the committee to develop the contacts that allow them to discuss issues like this (albeit at a much more challenging level).

Answers from Francis

Answer 1

It is really a matter of developing habits that work in general. In the days when the above code would necessarily have been C there is no advantage one way or the other and programmers became accustomed to using a post increment. The compiler almost certainly generated absolutely identical code so we just wrote what seemed most natural. Then along came C++ with the potential for user defined post- and pre-increment. (The early versions of C++ did not allow these to be distinguished but pretty soon mechanisms were provided so that programmers could define both).

In the case of pre-increment there is no problem, the user defined operator simply returns a reference to the object after whatever you decide pre-increment means has been applied. The problem comes with post-increment. How can we write a function with a delayed action? The answer is that we cannot. What we have to do is keep a copy of the un-incremented version, increment the original and then return a copy of the copy. Even with a clever compiler eliding one of those copies you still have to pay for at least one copy.

The conclusion is that if you have a choice, use pre-increment. With the increasing use of general iterators (pointers are just a special case) we should get in the habit of writing our code so that it works well with any iterator.

There is a second change that occurs because of the increasing use of general iterators and that is how we code the test for repeating the loop. The original idiom was to write iter<limit on the basis that this avoided the problem of jumping over the limit. Actually, with good coding discipline (never change a loop variable inside a loop) that does not happen. However with the growing use of iterators that test is no longer likely to work in all normal cases. There is no reason why an iterator for a deque (double ended queue) or a list should work appropriately. What we have to do is to check that we haven't reached the end. Hence the test is now more often coded as iter!=limit.

I think that understanding idioms is important so you will know when to ignore them, but it is also important to use the idioms appropriate to modern coding techniques.

Answer 2

It isn't my style, but in C++ where the scope of a loop variable is the life of the loop the idea certainly has some merit. However I would suggest that something like:

#define LOOPSTART (limit) for ( unsigned long int ctr = 0 ; ctr != limit; ++ctr) {

would work better as a generalisation.

Answer 3

Of course you do not need to be a Committee member to get help. However it is often easier to discuss issues with those you know rather than with faceless gurus. All the more reason for taking every opportunity to establish contact with as many others as you can. Being a Committee member is only one of several ways of meeting some experts. Conferences, Seminars and Standard Meetings are just three others that spring to mind.

Idris S Hamid Asked

My name is Idris S Hamid. I have a MA in Physics and a PhD in Philosophy, and am now an assistant professor. I am just starting on the road to learning C++ (my only other substantial programming experience is in TeX/LaTeX). I would like to learn C++, Java, and Qt (the cross-platform C++ GUI library of KDE fame) for developing TeX/LaTeX-related applications to use in my own research (W95, presently switching to Linux). I am thus interested in joining ACCU. Which of the four types of subscription would you recommend, and what is the cost in US dollars? Does the C++ Specialist Group cover Qt at all? Where do I send payment?

A question (if its ok with you): After carefully looking through your book reviews, it appears that the best two books to start me off on my journey may be "C++ Interactive Course'" by R Lafore (it got some of the best reader reviews on amazon.com; both they and your reviewer were iffy about the internet component) and "C++ From the Beginning'" by Jan Skansholm (which got the highest praise from your reviewer but no reader comments on amazon.com). Would you recommend either of these, both, or something else for someone in my position?

If you have any advice on how a novice like myself can get the most out membership in your association, then feel free to pass on any words of advice. Idris

Answers

from Reg Charney

Thank you for writing and asking to join the ACCU here in the U.S. WRT price and membership issues, I will refer you to the enclosed membership application form.

WRT my book recommendations, I would recommend the ones you mentioned. I would also mention Bruce Eckel's "Thinking in C++". His style is nice and easy and he is quite accurate. The book itself is available over the net.

See his site at http://www.EckelObjects.com/ .

Getting the most out of the ACCU involves getting involved. Currently, you can contribute questions and articles to our magazines Overload or C Vu. In the near future, we plan to have email reflectors, one will be specifically designed for newcomers and students.

If you have any other questions, please feel free to contact me or others in the ACCU. Again, thanks. Reg.

Francis' Addendum

Setting people like Idris on the right track is important because others will seek and follow his advice. One major problem is that people tend to recommend what worked for them. In the fast changing world of C++ this will often result in poor advice. If you learnt C++ more than ten years ago you were likely to have been a C programmer already and you might well have learnt C++ from 'The C++ Programming Language' (1st edition). You might think that the best way to learn C++ was to learn C first, then study the same book (perhaps in its latest edition). If you find that silly, I can assure you that such recommendations are far from unusual.

Over the last few years two things have been happening: C++ was being developed and extended and our understanding of how to use C++ has been maturing. Whatever my current first choice would be for someone such as Idris (I think Eric Nagler's Learning C++ - A Hands-On Approach 2nd edition is a good contender) you can be pretty certain that it would be different by this time next year. I know of at least one excellent contender currently being written.

Let me offer a few criteria for a modern book on C++ for newcomers:

  • It does not assume familiarity with C

  • It does not insist on first teaching you C mechanisms (for strings, arrays etc.)

  • The example code will run on current compilers (therefore namespace  must be handled somehow)

  • It uses the STL in simple ways.

Please note that we have just added a mailing list . This is a moderated list to ensure that inappropriate questions (please do my homework) are not posted and likewise for answers (helping with homework generated questions OK, doing the work is not). I hope that a good number of the ACCU 'experts' will lurk on this list so they can field questions in their areas of expertise.

To a large extent, the more you put into ACCU, the more you get out. There are a few exceptions among our most expert members.

Questions from Anthony Pleace

Dear Francis

I am a teacher in a Design and Technology Dept of a secondary school. I have Borland turbo C++ ver 3 for DOS and am a member of ACCU. I am not good at programming. I have a pupil who has built a device which measures the length of pulses produced by a lighting unit in order to understand how the lighting unit works.

I have built a parallel to serial interface for the pupil so that the information can be captured by a computer and inspected for any patterns.

My device will produce RS232 data in a constant stream at 9600. Can you help me to sort out how to get this raw data which might be any value including 0x00 and 0xff into the computer and then into a file. I have found a program called TXNUL on C Vu disc 10.1 but I cannot find any associated articles.

You could help by

  1. How do I get back issues of C Vu I think that I want Sept 97 to go with TXNUL

  2. Can all binary values be successfully transmitted to the serial port

  3. How do I store the information in a file in real time? Do I collect the data in an enormous array (1K bytes??) and then put it into a file or will file storage work successfully at this speed 9600?

  4. If you are unable to help can you point me in another direction

Not being an expert in this field I forwarded his request to a couple of ACCU's experts in that field. Francis

Answers from Brian Bramer

I looked in past C Vus for article on TXNUL and cannot find anything. (I do not think there were any Francis)

However I attach some files (these will be on this issue's disk)

rs_lib.h

header file with prototypes of functions for serial line

library rs_lib.c

implementation file of serial line library

terminal.c

test program uses the above as a simple terminal emulator

You compile terminal.c so:

  tcc terminal.c rs_lib.c

and assuming your experiment is attached to serial port COM2 at 9600 baud run the terminal emulator so

  terminal -port=com2 -baud=9600

You should see any printable characters from your experiment. You can then write a program to acquire your data and process it as you wish.

rs_lib.c uses interrupts to read characters and stores them in a ring buffer rs_data of length rs_length which is currently 1024 bytes - you can increase this if necessary, i.e. if you get overrun errors. You call the rs_getch() functions to read the characters from the ring buffer.

This will read null characters and 0xff without problem under DOS and so long as your have a reasonably fast machine it should work OK at 9600 baud.

You may need to run you PC in DOS mode.

Let me know if you have any problems

While this fixed the direct problem, I think it highlights an area where a couple of simple articles might be welcome. I know you can go and buy a book on the subject, but not everyone wants to wade through such material trying to decide whether the author is an expert at electronics or at programming (very few are both).

Question from Jeff Spence

I am a novice-hobbyist and a fairly new member of the ACCU. I am currently learning C++ via C++ Primer (Lippman & Lajoie). The book was recommended by the ACCU and I am very satisfied with it. However, it seems to me that this book, as well as some other books I purchased prior to my membership, do not discuss the creation and management of data files in great detail. Should I be satisfied with what is offered in "C++ Primer" and eventually develop the necessary skills on my own, or should I seek another source to compliment my learning? Also, are there other areas that I should be concerned with so as to learn all that a good programmer needs to learn? Thank you for your time.

Answers?

Over to you, dear reader.

A Quick Question from Richard Howells

On a recent C++ class a student asked me about resources for setting C++ programming standards.

I'd be interested if you could suggest any good books, or other resources.

I checked the web site and I did not find anything obvious there.

I think this question is about C++ programming guidelines. The best book on the subject is Industrial Strength C++ by Henricson & Nyquist. Large Scale C++ Software Design by Lakos should also be on their reading list.

What do readers have to add? Particularly with regards to other resources. Francis

Notes: 

More fields may be available via dynamicdata ..