Departments


We Have Mail


Mr. Plauger,

I am a subscriber of The C Users Journal and I have been enjoying it from I started my subscription. In particular I want to ask you something. I am working in a project that requires sophisticated and unusual macros. Working on them I realized that the following code:

{
   int i=1;

   (1, i)++;

   printf("Value of i is %d\n", i);
}
will print:

Value of i is 2
This makes sense to me. But I have tried to compiled with four different compilers:

Sun ANSI C Compiler complains saying that the result of 1 is not a LHS value. It is certainly not.

GNU C Compiler compiles and executes correctly.

Sun C++ Compiler compiles and runs correctly

Because I am getting two different results with two compiler that are supposed to be ANSI compliant, which one is the correct one? Is the construction valid? Thank you very much for your help. And sorry to bother you with this kind of simple questions.

Daniel M. German
dmg@cs.wm.edu

Believe it or not, all compilers are behaving properly. The C Standard says the result of a comma operator is an rvalue, and the ++ operator is defined only for modifiable lvalue operands. Applying ++ to an rvalue is thus undefined behavior, which leaves implementations free to do as they choose. The strictest approach is to issue a diagnostic, as the Sun ANSI compiler does. But a common extension is to find some lvalue behind the rvalue and apply ++ to the lvalue. That's what the other compilers seem to be doing.

For what it's worth, I was the one who screamed loudest that the comma operator (and a few others) be rvalues. Hope this helps. pjp

Dear Mr. Plauger,

In the July 1991 issue of CUJ, Jonathan Walker III had a lovely article in which he presented an algorithm for positioning a generalized tree. Last spring and summer, a student and I wrote a couple of programs utilizing this algorithm. These programs take bracketted output from syntactic and morphological parsers and display visual representations (trees) in an X-window or a large curses pad (and use the vi keys, hjkl, to navigate through various parts of the tree). The X-window version has been tested on Sun3s, Sun4s, and MIPS machines, and the curses version on Suns, PCs running XENIX, and PCs running MS-DOS. There is also a primitive version using Borland's bgi for MS-DOS.

We would like to make these programs available for use by linguists by putting them in an ftp site. Last summer I wrote to Mr. Walker at the address given in his article to ask for permission to do this (his code makes up about 25% of each program). I haven't received a reply from him, and I'm writing to you to ask first if CUJ has a more recent address for him), and secondly if, failing that, it would be possible for CUJ to give up permission to use the code in these small, public-domain applications.

On another topic, I've been a subscriber of CUJ since I found out about it a few years ago, and have enjoyed it immensely as well as learned a great deal from it. I particularly enjoy your articles on Standard C. (At my age, 50, I give myself the luxury, however of sticking to K&R C (the first edition). I'm professionally a linguist, anyway, and not actively involved in training programmers. I've noticed that the computer science students I work with all code in Standard C.

With many thanks for your help,

Chet Creider
<creider@csd.uwo.ca>

Diane Thomas, CUJ Managing Editor responds:

All CUJ code is now posted on USENET. Please check the notice about online source code located in the table of contents for details.

Dear P.J. Plauger,

My copy of the Journal arrived yesterday, and I was pleased to see the usual broad range of articles. I found your column of particular interest, as I have recently reviewed some of the coding errors that I make. I hope that the Journal will not drift too far from C to C++, as I consider C++ to be a very different language, requiring different design considerations and often used for very different projects. Perhaps you could consider a little coverage of Objective C, which appears to me to be a much more helpful framework for OOP.

The article "Time Complexity" by Wilbon Davies (page 31) displays a misunderstanding of the bubble sort. The code shown is incomplete, exaggerating the time taken:

      swap = 1;
      while (swap == 1) {
        swap = 0;
        for (i = 0; i < n - 1; i++) {
          if (x[i] < x[i + 1]) {
            tmp = x[i];
            x[i] = x[i + 1];
            x[i + 1] = tmp;
            swap = 1;
          }
        }
      }
A practical bubble sort expands this simply, collapsing the scope of the sort faster. Where the data is already sorted, only (n - 1) compares are performed, partially and randomly sorted data require progressively more work. The worst case is for reverse sorted input, where no improvement is made over the published form. Keeping the format above:

      last = n;
      while (last > 0) {
        limit = last - 1
        last = 0;
        for (i = 0; i < limit; i++) {
          if (x[i] < x[i + 1]) {
            tmp = x[i];
            x[i] = x[i + 1];
            x[i + 1] = tmp;
            last = i;
          }
        }
      }
A number of improvements can be made to this algorthim to give acceptable execution time, and reduce worst-case behaviour. In particular alternating between sorting forwards and backwards, this collapses the scope of the sort still faster. It also has the benefit of moving worst-case execution from a reverse sorted input, to an esoteric order to require the maximum exchanges. In several applications I have had the task of sorting large structures, rather than pointers, with the primary constraint on use of memory. I have found that an optimised version of the Bubble Sort has given very acceptable results.

This incorrect version often features in articles comparing sort methods. The problem seems to be that the authors find it in several refernce books. In these books it is introduced briefly, only for a paragraph discussing its worst case operation. I would very much appreciate if articles in your Journal refering to "fastest bubble time," or similar, actually use the practical version, rather than propagate the brain-dead one on this occasion.

I am happy to discuss this further, and you may edit the letter if you wish to publish it in the journal.

Yours sincerely,

Anthony Naggs
Software/Electronics Consultant)
Email: amn@vms.brighton.ac.uk
P O Box 1080,
or xa329@city.ac.uk
Peacehaven,
East Sussex
BN10 8BT
Phone: +44 273 589701
Great Britain

When Kernighan and I wrote The Elements of Programming Style, we discovered that "improving" a bubble sort often made it run slower rather than faster. Naturally, you can favor certain patterns of input to advantage. But the extra baggage you add generally slows average behavior for random input. A "brain dead" bubble sort is quite fast enough for sorting small quantities of data. For sorting large quantities, you're better off switching to a better algorithm than gilding this particular lily. Optimizations can pay off in the middle region, if you can determine what that is. pjp

Dear P.J.:

Is there an e-mail address for the C Users Journal? I didn't receive the September '92 issue and, being a hard-up student, want to avoid the cost of an international phone call to sort it out. By the way, I would also like to commend you on the thoughtfulness and intelligence of your writing, I appreciate it very much.

Thanks,

Jane Anna Langley
105 Osborne Street
South Yarra
University of Melbourne
Victoria 3141
AUSTRALIA
(613) 03 820 3629
s342046@emu.insted.unimelb.edu.au

Diane Thomas, CUJ Managing Editor, responds:

All questions regarding subscriptions or any other customer relations topic can be sent to cujsub@rdpub.com

Just to start off, I find the magazine that you publish is the best that I have come across. To better clarify this, I appreciated the points you brought up in the Editor's Forum about product reviews and how the magazine stands on the issue.

After reading that, I examined the editorial box to the right of the article and I believe I have found a mistake. Under trademarks, OS/2 is listed under the competitor's company, Microsoft. In the article, "Debugging with Assertions" on page 42, there is an error in the code in listing 2:

   void CheckEmpty() {
      assert(StackPtr = 1)
   }
It should be as follows:

   void CheckEmpty() {
      assert(StackPtr == 1)
   }
Keep up the good work!

Sincerely

Eric V. Blood
ericb@sierra.com

Thanks.pjp

Dear Mr. Pugh,

To gain control of the specific area of the screen scrolled when printf does a line feed from the last row, I installed my own video interrupt service routine (ISR) for int10h. My ISR chains to the original ISR after testing AH for function code 6 (scroll up). If (and only if) AH==6, my ISR replaces the value in CH with a row number passed from the calling program before chaining to the original ISR. This gives the calling program a method of preventing data above a given row from scrolling off the screen, as long as scrolling is done by int10h calls. (Some compilers implement cprintf, cputs, and putch of <conio.h> so they can scroll up without using int10h.)

My test program reports the vector of the original video ISR and the vector of the my replacement ISR. A test version of my ISR displays a signature on row 14 of the screen whenever AH==6. The signature consists of the char equivalents of CH (0), CL (0), DH (24), DL (79), AH (6), AL (1), and the value to be put into CH (from the calling program. CH,CL is used by the original ISR as the upper-left row,col of the window to be scrolled, while DH,DL is used as its lower-right row,col. AL is the number of lines to be scrolled.

On a PC Designs XT with Hercules video under DOS 3.1, the test program and my ISR work as expected. On an AST Premium with VGA under DOS 3.3, my ISR is not called at all, as indicated by the absence of the diagnostic signature, even though the vectors reported show that my ISR was properly installed. The same failure was noted on a Packard-Bell with EGA under DOS 3.3.

Suspecting that EGA/VGA video subsystems bypass int10h for all scrolling functions, I studied PC & PS/2 Video Systems (Richard Wilton, Microsoft Press, 1987), Programmer's Guide to the IBM PC (Peter Norton, Microsoft Press, 1985), and back issues of C Users Journal and Dr. Dobb's Journal. I found nothing that either confirmed or dispelled that notion.

Can you offer any suggestions that may lead to an answer to this puzzle?

Thank you,

Sid Sanders
5 Seneca Avenue
Geneseo, NY 14454-9508

Sure looks like a bypass to me, but I'm hardly an expert in this area. Anybody out there got any ideas? I suggest you contact Mr. Sanders directly for speed. Send us a copy of your letter if you think the lore is worth sharing. pjp

Re your editorial in the October 1992 C Users Journal:

I bought a copy of the Shamus Software library MIRACL to fiddle with p. It has many mathematics routines and some top coding and decoding stuff. So I ported it to Coherent 310 and now to Coherent 401 which is the 32-bit system. I could compute p to 500 places in the 16-bit system and it does much more in the 32-bit version. I can get 50,000 places, but it takes 57 hours! It yields a 12 page printout and I am not sure of its accuracy at this time. I would like a copy of the "Spigot" algorithm originally due to Stanley Rabinowitz which really works. I got one in an article by Peter Morrison on comp.lang.c which produces rubbish only.

Also the Coherent 401 produces LOTTO programs with one million games in them. Of course it takes up 39 Mbytes but I use grep to see how many winning games are in the file.

I tried porting the MIX Multi-C library to Coherent but it is no good. There may be a bug in the way coherent uses the typedef enum. It has a definition of ECODE in the file mtc_defs.h. This reads typedef enum { 13 names of errors.. } ECODE. Then it has the line:

typedef ECODE (*TRAVERSE_FUNC) (void*,
void*, int, int, void*);
This is not acceptable to the compiler, which produces this message:

58: mtc_defs.h: missing ')'
58: mtc_defs.h: missing semicolon
58: mtc_defs.h: declarator syntax
58: mtc_defs.h: external syntax
Have you got any ideas on what I can do with this?

Jonathan Kitchin
Perth, Western Australia
jon@dialix.oz.au

Once a compiler produces a diagnostic, it often gets confused for awhile. Try omitting the earlier statement (or fixing it if you know how). There's a good chance the subsequent diagnostics will evaporate. pjp

Dear Sir,

Some time ago, I purchased your book, "The Standard C Library," together with the code disk. I just thought I would pass on that it has been one of the better investments I have made in computer science books. I find it very instructive and a good source of ideas and algorithms. (I recently had to implement malloc on an embedded system with no operating system! Studying how you did it gave me a good kick start.)

I read your "Standard C" column on bugs (CUJ September 1992) with great interest. I wish there were more articles about people's bugs and problems. I think we could learn more from them than from some of the "how to do it" articles. No doubt you have received other letters on this, but there seems to be a bug in your bug fix. [Bug report omitted. Same as earlier reports — pjp] I hope that this bug did not creep into the v1.1 code disk.

Speaking of the v1.1 code disk. You mentioned in the column that it now available, but I couldn't see anything in CUJ about how to order it. Do you need some "proof of ownership" for the upgrade? I can't see a serial number on the disks. Or do you rely on your purchase records? [MasterCard number omitted, for obvious reasons. — pjp]

Yours faithfully,

Ian Cargill
54 Windfield
Leatherhead
Surrey
KT22 8UQ