Pwers of C (was: Precedent for use of =)

AAAARRRRGGGGv argv at sri-spam.ARPA
Thu Jul 10 16:47:20 AEST 1986


In article <2306 at umcp-cs.UUCP> chris at maryland.UUCP (Chris Torek) writes:
>I have come to favour
>
>	if ((prog_name = rindex(*argv, '/')) != NULL)
>		...
>
The simple fact that C lets you evaluate expressions within if statements
(thus saving extra unneeded and combersome code) is reason enough not to
"overevaluate" expressions or to perform expressions in one statement and
to evalute results in the next.

Why do the above, when in my first example:

if (prog_name = rindex(*argv, '/'))

is all that's needed. Those who understand the language properly know that
"progname" and the return of rindex() (or any function or variable) are
one and the same in value and the if statement is evaluating that value.

Given that sometimes there may be "tricky" expressions, it is up to the
programmer to comment code well enough so that quick skims of said code
won't confuse the reader too much.  I strongly believe that code should
NOT be made less efficient for readability issues.  Readability can be
made acceptable to even novice programmers with efficient use of comments
and descriptive variable names -- both of which have no effect on the
speed of code.

If people would stop fighting C, but take advantage of what it has to offer
over other langages (like the above example and more -- bit manipulations,
etc..), then they would become better programmers themselves.

I believe that most are sick and tired of this discussion, so I'll try
to spice something up myself with the following scenario...

I like to use my own error statements and print statments for better
control as described below..

/*VARARGS*/
print(fmt, args)
register char *fmt;
char *args;
{
    /* other type of actions done here */
    _doprnt(fmt, &args, stdout);
    fflush(stdout);
}

/*VARARGS*/
error(fmt, args)
register char *fmt;
char *args;
{
    /* additional actions done here */
    print(fmt, args);
    print(": %s\n", sys_errlist[errno]);
}

as you can see, I'm using "print" like printf, and it works fine.
"args" can be declared as basically anything since I'm passing the
address of it to _doprnt (I can see it now; people are going to tell
me to use int, others will claim *int, and some will agree with my
useage, maybe "caddr_t"?).

error() is like "perror" except that it is now (functionally) like
printf(). The problem is that error can only take one additional
argument than "fmt" -- that is:

error("can't open %s", filename);

will work.. you might get something like:
"can't open foobar: no such file or directory"

However, additional args like:

char *mode = "w";
...
error("can't open %s for \"%s\"", filename, mode);

will produce:
"can't open foobar for "(null)": no such file or directory"

The reason is that error is receiving the args right, but since
its address is being passed to print(), only the address of the
first arg can be seen by print, thus, all the rest of the args
that _doprnt finally sees are NULL's.

The qustion (at last) is, how can a variable number of args be
`elegantly' passed to error and then passed to print so that
the _doprint in print() sees all the arguments.

There are various ways which come to mind; none of which I like:

1) declare error as:
     error(fmt, arg1, arg2, arg3, arg4)
     char *fmt, *arg1, *arg2, *arg3, *arg4;
     {
	 print(fmt, arg1);
         ...
     }
   This works as long as there are no more than 4 args... not good,
   but feasible if you make sure you don't do it. Also, sloppy, but
   portable.

2) format the args first into a string:

    error(fmt, args)
    char *fmt, *args;
    {
	static char buf[SIZE];
	static FILE &foo;
	/* proper initialization of foo fields including
	 * foo._ptr = buf;
	 */
        _doprnt(fmt, &args, &foo);
	print(buf);
	...
    }

   I don't like this because you're limited by "SIZE", and it seems to
   be doing much more work than necessary.

3) use varargs to split all the args into a double array of char and then
   pass the address of the buffer to print.  yuk.

I don't like these because it seems to me that this is straight forward
enough to be done simply and elegantly -- how, I don't know. I hope that
someone can add some light to this problem.

dan  <argv at sri-spam.arpa>

"Wouldn't ya like to be a pointer, too...
     (be a pointer, be a double pointer, [repeat and fade])"
-------------



More information about the Comp.lang.c mailing list