Re: [LONG] Strange occurencies in Borland makefile

From: Henrik Stuart (hstuart@inoyfb.com)
Date: 06/02/02


Greetings,

On Sunday, June 02, 2002 2:49:16 PM Thomas Arp wrote:
> I'm trying to help a user of the dg scripts package port it to borland.

> C:\mud\circle30bpl21\src>make -fmakefile.bcc55
> MAKE Version 5.2  Copyright (c) 1987, 2000 Borland
>         Bcc32 -P- -c @MAKE0001.@@@
> Warning W8008 alias.c 72: Condition is always false in function read_aliases
> Warning W8066 alias.c 72: Unreachable code in function read_aliases
> Warning W8008 alias.c 100: Condition is always false in function
> read_aliases
> Warning W8066 alias.c 100: Unreachable code in function read_aliases
> <snip of working files>
> Warning W8008 ban.c 64: Condition is always false in function load_banned
> Warning W8066 ban.c 64: Unreachable code in function load_banned
> <snip because you get the picture now>

[snip]

> Further investigation proves it to be the condition
>  if ((number) * sizeof(type) <= 0) \
> that is always false. The error occurs every time 1 is passed as the last
> parameter. I have tried changing the macro as follows:

> #define CREATE(result, type, number)  do {\
> !  if ((number) <= 0) \
>      log("SYSERR: Zero bytes or less requested at %s:%d.",
>          __FILE__, __LINE__); \
>    if (!((result) = (type *) calloc ((number), sizeof(type)))) \
>     { perror("SYSERR: malloc failure"); abort(); } } while(0)

   The  second  function  is  identical to the first in that the first
   if-block  will always be false, so changing in such manner will not
   change  it in any way. You're in effect trying this: if (1 <= 0)...
   see further description below.

   ---

   Since  you're  passing  1 as number you have: if (1 <= 0) which is,
   obviously,  always  false, and hence the ensuing code: log("SYS...)
   will  be  unreachable  -  hence warnings 1 and 2 on line 72, and in
   subsequent  places  it warns about. This explains all the CREATE(x,
   y, 1); calls.

   Now to the rest...

   First  of,  strlcpy  isn't  prototyped  so  it'll cause an error on
   compilation,  so  a  proper  insertion  somewhere  in  sysdep.h  or
   likewise using:
     size_t strlcpy (char *dest, const char *src, size_t copylen);
   should  do  the trick. Please note that I haven't actually tried to
   link  and  run the entire thing so I don't know whether Borland has
   the  strlcpy  routine, but given their usual dedication to standard
   conformance I would be surprised if they do not.

   Second, in several places in the code there will be warnings like:
   W8004  file.c  line:  'variable'  is assigned a value that is never
   used in function _function name_.
   These  can  safely  be  disregarded  as  they  are  just  courteous
   information supplied by the compiler.

   In  the  following I will suppose that strlcpy has been declared as
   well   as   PATH_MAX.  Will  also  presume  that  you  ignore  the
   CREATE(x,y,1)'s  in the output. I'll present a possible solution at
   the bottom of this mail.

   act.informative.c:
   ------------------
   205: condition always true:
     inspect  the  struct.. byte is a typedef for unsigned char. I.e.,
     it's  _never_  negative, so the last entry of -1 should, in fact,
     be  the  same as 256 or whichever the largest unsigned char value
     is  on  the system. Now, this means that the halting condition in
     the  loop  in  line  205  (diagnosis[ar_index].percent >= 0) will
     _always_  be true - in other words an infinite loop. A correction
     to  this  problem would probably be to change the byte percent in
     the struct to an integer.

   1414: always false: if (len + nlen >= sizeof(buf) || nlen < 0)
     we  here  observe  that len and nlen are of type size_t that is a
     typedef  of... unsigned int. In other words the latter condition:
     nlen < 0 will always be false, given the nature of unsigned ints.

   1430: same as above

   act.wizard.c:
   -------------
   1945: same as above
   2026: same as above
   2039: same
   2052: same

   class.c:
   --------
   1940, 1970, 2000, 2030, 2087, 2117, 2147, 2177:
     these  all  originate  from  the  break;  statements in the title
     sections.  Since  all states (especially default) return a value,
     this  statement  will  never  be  reached...  it's  granted  nice
     programming  style  to  remember to add them, but nevertheless...
     they will never be reached.

   db.c:
   -----
   654:  function specifies a return value but terminates with an exit
   statement.  the  function  still  requires  a  return  since  it's
   specified, hence W8070: "Function should return a value in function
   count_alias_records"

   The  error in compilation in this file is, as Welcor states, due to
   PATH_MAX  not  being  defined. The same goes for Visual C++, by the
   way.  Personally,  I  just  changed  all places in the code reading
   PATH_MAX  with  MAX_STRING_LENGTH,  but perhaps it would be nice if
   the standard bundle sorta solved this *cough*.

   mail.c:
   -------
   312+313:  Borland  C++ sees the constant comparison in the if-block
   for what it is and actually computes the values. Since the if-block
   won't  ever be true for Borland's purposes the ensuing code (a core
   dump)  will  never be executed and is thus unreachable. Ignore this
   warning or add an #ifndef to match Borland.

   spec_procs.c:
   -------------
   142: same as act.informative.c line 1414.

   utils.c:
   --------
   308: same as above

   --------

   This  concludes  a  rather long list. As such I find it hard to see
   why  the  other compilers haven't complained about at least some of
   these  (like  the  infinite  loop  in act.informative.c:205), but I
   suppose  that  they  are able to recognise the values specified and
   see  that  none  go  over  127  and thus fit into a signed char and
   promote  it  to  that,  even  though  this  is, as far as I recall,
   outside of the C specification.

   To fix the CREATE bug I tried to create a new macro...
   #define CREATE1(result,type) do {\
     if (!((result) = (type *) calloc(1, sizeof(type)))) \
       { perror("SYSERR: malloc failure"); abort(); } } while(0)

   This   isn't   an   aesthetically  pleasing  solution,  but  since
   definitions  cannot  be operator overloaded this is, unfortunately,
   the  only  solution I could come up with, other than redoing CREATE
   as a function rather than a macro.

   I hope this helps any eventual Borland users out there.

--
Yours truly,
  Henrik Stuart (http://www.unprompted.com/hstuart/)

--
   +---------------------------------------------------------------+
   | FAQ: http://qsilver.queensu.ca/~fletchra/Circle/list-faq.html |
   | Archives: http://post.queensu.ca/listserv/wwwarch/circle.html |
   | Newbie List:  http://groups.yahoo.com/group/circle-newbies/   |
   +---------------------------------------------------------------+



This archive was generated by hypermail 2b30 : 06/25/03 PDT