another CXX question

From: Chip Coldwell (coldwell_at_gmail.nospam)
Date: 07/25/05


Date: Sun, 24 Jul 2005 19:12:50 -0400


The following code is excerpted from the lexer in Xpdf:

#include <ctype.h>
#include <stdio.h>

int main(int argc, char *argv[])
{
   const char *str = "3.14159";
   int c, xi;
   double xf, scale;
   bool neg;

   while(c = *str++) {
     switch (c) {

     case '0': case '1': case '2': case '3': case '4':
     case '5': case '6': case '7': case '8': case '9':
     case '-': case '.':
       neg = false;
       xi = 0;
       if (c == '-') {
         neg = true;
       } else if (c == '.') {
         goto doReal;
       } else {
         xi = c - '0';
       }
       while (1) {
         c = str[1];
         if (isdigit(c)) {
           str++;
           xi = xi * 10 + (c - '0');
         } else if (c == '.') {
           str++;
           goto doReal;
         } else {
           break;
         }
       }
       if (neg)
         xi = -xi;
       printf("integer value = %d\n", xi);
       break;
     doReal:
       xf = xi;
       scale = 0.1;
       while (1) {
         c = str[1];
         if (!isdigit(c)) {
           break;
         }
         str++;
         xf = xf + scale * (c - '0');
         scale *= 0.1;
       }
       if (neg)
         xf = -xf;
       printf("floating-point value = %d\n", xf);
       break;

     default:
       puts("non-numeric character");
       break;
     }
   }
   puts("done lexing");
}

When compiled with no options, it generates this error:

$ cxx/version
Compaq C++ V6.5-046 for OpenVMS Alpha V7.3-1
$ cxx foo.cc

       if (neg)
......^
%CXX-W-CODEUNREACHABLE, statement is unreachable
at line number 54 in file DISK$USER:[COLDWELL]FOO.CC;8

And the compiler really means it -- it optimizes out the unreachable code.

The line the compiler is complaining about is the one at the end of the
"while(1)" loop under the "doReal:" label where the lexer is lexing a
floating-point number. There's all kinds of fishy things going on there
(jumping to a goto-label in the middle of a bunch of switch-labels?!?),
but nonetheless I think the C++ standard requires that the "break" in the
"while(1)" loop should break out of the loop, not the enclosing switch.

I fixed the problem thus:

     doReal:
       xf = xi;
       scale = 0.1;
       while (1) {
         c = str[1];
         if (!isdigit(c)) {
           goto doneReal;
         }
         str++;
         xf = xf + scale * (c - '0');
         scale *= 0.1;
       }
     doneReal:
       if (neg)
         xf = -xf;
       printf("floating-point value = %d\n", xf);
       break;

and now I have a working Xpdf v3.00pl3 (compiled with Freetype 2.1.10 and
T1Lib 5.0.2 -- stay tuned for an announcement).

Chip

-- 
Charles M. "Chip" Coldwell
Turn on, log in, tune out


Relevant Pages

  • Re: Fridays the thirteenth. (And a little puzzle.)
    ... -- compiler) is the usual method ... int febdays ... -- We're going to go round a loop dealing with each year in turn. ... -- other languages call) ...
    (uk.people.silversurfers)
  • Re: c# interview question
    ... particular version of the compiler happens to generate. ... internally will call Concat(string, string). ... shows the second loop runs 5-10pc quicker than the first loop. ... int s1 = System.Environment.TickCount; ...
    (microsoft.public.dotnet.languages.csharp)
  • Re: Should I use mutex in this context?
    ... someglobal isn't changed by the loop body or any function it calls -- ... int a ... The compiler changes this to: ... of the loop. ...
    (microsoft.public.vc.language)
  • Re: Should I use mutex in this context?
    ... someglobal isn't changed by the loop body or any function it calls -- ... The compiler has preserved ... int a ... of the loop. ...
    (microsoft.public.vc.language)
  • Re: optimizers are overrated
    ... int i = 100; ... The optimizer has no excuses. ... I specified the used compiler flags. ... The test is the whole point of optimizing this loop on x86. ...
    (comp.lang.c)