[Wylug-help] C++ code

Roger Leigh roger at whinlatter.uklinux.net
29 Oct 2002 22:55:41 +0000


Philip Wyett <philipwyett@dsl.pipex.com> writes:

> --
> On Sun, 2002-10-27 at 23:33, Roger Leigh wrote:
> > Roger Greenwood <rg@nthong.freeserve.co.uk> writes:

[serious snip]

> > > 		num = int(numd);
> >                       (int) numd; /* no int() function call! */
>

> No int() function call? That is a valid way to enforce a type cast as
> the method you used. both 'blah = (type)foo;' and 'blah = type(foo);'
> are valid and comes with personal style preference. My preferred is the
> method you employ, as it leaves no room for mis-interpretation.

Thanks for the correction, I didn't realise that was valid cast syntax.
I'm not too keen on the latter, since it looks like a function call
(and could probably clash if you name a function after your own
typedef'd type??).

> In the above code is constants like EXIT_SUCCESS, BUFSIZE etc. If these
> are define constants, they are dangerous. In small programs they are
> fine, you can easily track them. However in larger projects, they often
> become the source of bugs and are difficult too debug due too their
> nature. The preprocessor merely replaces the word representation with
> the value, not caring what it is aka the type or any relation too other
> code.

This is true.  However, EXIT_SUCCESS is defined in stdlib.h, and
BUFSIZ is defined in stdio.h.  They are both IIRC defined by POSIX,
and so they are perfectly reasonable to use.  BUFSIZ is 8,192 bytes on
GNU/Linux and is the optimum size for efficient stream I/O, and buffer
operations.  (With glibc 2.3, FILE I/O is mmap-based, making buffering
there redundant.)

See libc.info, nodes "Exit Status" and "Controlling Buffering":

,----[ exit ]
|    *Portability note:* Some non-POSIX systems use different conventions
| for exit status values.  For greater portability, you can use the
| macros `EXIT_SUCCESS' and `EXIT_FAILURE' for the conventional status
| value for success and failure, respectively.  They are declared in the
| file `stdlib.h'.
`----

,----[ Macro: int BUFSIZ ]
| The value of this macro is an integer constant expression that is
| good to use for the SIZE argument to `setvbuf'.  This value is
| guaranteed to be at least `256'.
|
| The value of `BUFSIZ' is chosen on each system so as to make stream
| I/O efficient.  So it is a good idea to use `BUFSIZ' as the size
| for the buffer when you call `setvbuf'.
|
| Actually, you can get an even better value to use for the buffer
| size by means of the `fstat' system call: it is found in the
| `st_blksize' field of the file attributes.  *Note Attribute
| Meanings::.
|
| Sometimes people also use `BUFSIZ' as the allocation size of
| buffers used for related purposes, such as strings used to receive
| a line of input with `fgets' (*note Character Input::).  There is
| no particular reason to use `BUFSIZ' for this instead of any other
| integer, except that it might lead to doing I/O in chunks of an
| efficient size.
`----

> An example is 'pi'. Many do:
>
> #define pi 3.141592653589793
>
> while
>
> const float pi = 3.141592653589793;
>
> is safer because the compiler and debugger are left in no doubt what it
> is and can work with it. In the last project I was brought into. 15% of
> the pre-release bug count was down to #define and some creative define
> macros problems. I always encourage not using them wherever possible and
> opting for the safer option IMHO.

I totally agree; I've seen my own share of problems with macros.


Regards,
Roger

--
Roger Leigh
                "Liberty and Livelihood" - Support the Countryside Alliance
                Need Epson Stylus Utilities? http://gimp-print.sourceforge.net/
                GPG Public Key: 0x25BFB848 available on public keyservers