From: Keith Thompson said:
It would catch more errors.
More likely generate bogus errors. For example:
% more tryll.c
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
...
(the declaration for strtoll is located in stdlib.h)
Reference:
<
http://www.delorie.com/gnu/docs/glibc/libc_423.html>
20.11.1 Parsing of Integers
The `str' functions are declared in `stdlib.h' ...
...
Function: long long int strtoll (const char *restrict string, char
**restrict tailptr, int base)
% gcc tryll.c -Wall
(compiles without warnings)
% gcc tryll.c -Wall -ansi
tryll.c: In function `tryParseLliTalk':
tryll.c:53: warning: implicit declaration of function `strtoll'
(that's a totally bogus warning, given that stdlib.h is included)
Perhaps -ansi might be of some value later when I'm writing actual
examples of how to do specific things. But right now strtoll is
used only to convert the decoded HTML FORM field from string to
integer so that I can *later* use that numeric value to demonstrate
arithmetic and other functions that require integers as input,
allowing the user to vary the particular integer value being used
as input simply by changing the contents of the form field.
% gcc tryll.c -Wall -pedantic
In file included from tryll.c:3:
/usr/include/stdlib.h:111: warning: ANSI C does not support `long long'
/usr/include/stdlib.h:117: warning: ANSI C does not support `long long'
tryll.c:5: warning: ANSI C does not support `long long'
tryll.c: In function `printflld':
tryll.c:6: warning: ANSI C does not support the `ll' length modifier
tryll.c:11: warning: ANSI C does not support `long long'
tryll.c: At top level:
tryll.c:25: warning: ANSI C does not support `long long'
tryll.c: In function `mystrtoll':
tryll.c:27: warning: ANSI C does not support `long long'
tryll.c: In function `tryParseLliTalk':
tryll.c:49: warning: ANSI C does not support `long long'
tryll.c:57: warning: ANSI C does not support the `ll' length modifier
tryll.c:62: warning: ANSI C does not support the `ll' length modifier
That's even worse at emitting worthless crap that's of no use to me
at this time. Maybe later when I'm making examples of code, this
might allow me to flag anything that's not usable outside the GNU
environment. For now, that would just present so much noise that
I'd never see a signal of an *actual* error in my code.
% gcc tryll.c -Wall -W
(compiles without any warnings)
You wrote:
c = c<<4 + h;
which you apparently wanted to be evaluated as
c = (c<<4) + h;
but it actually *means*
c = c << (4 + h);
because the "+" operator binds more tightly than the "<<" operator.
gcc was kind enough (and clever enough) to warn you about this.
Ah, well I didn't write that, Peter Burden wrote it, see link here:
<
http://www.rawbw.com/~rem/HelloPlus/hellos.html#c3>
So you're saying his code has a bug in it?
Hmm, I tried putting special characters into the FirstName field in that
form, and indeed it failed to decode it correctly. For example,
when I enter into the field
foo&baz
it gets urlencoded as
firstname=foo%26baz
but Peter's decoder give me:
For key [firstname] the value is [foo].
which is probably actually internally
foo<NUL>baz
where <NUL> prematurely ends the %s printf of the string.
Let me try putting parens there to make the nesting of operators
correct, done, recompiling cgis.c, done, rebuilding h3-c.cgi, done,
re-testing, horay, the bug is fixed, it now gives:
For key [firstname] the value is [foo&baz].
Thank you very much for the heads-up on this bug in Peter's code.
Now I need to comment that change I made in the code, done, and
update my description of it in hellos.html, done!!
If you don't believe me, try this program ...
I didn't need to. I just keyed special characters such as & and <
into my Web form, observed the hexadecimal encoding of them when I
asked lynx to show me the full URI (using GET method the urlencoded
form contents are after the ? mark in the URI), and then compared
to what came through after decoding as I showed above.
If you find yourself using spacing to indicate grouping in an
expression, I suggest you use parentheses instead.
Any time I need to look at the operator precedence table, it means
I shouldn't bother, use parens instead. That's what I do in all my
code. But this was Peters, and it was posted for public use, and
despite one mismatched prototype/definition pair (which I fixed,
and assumed had been left in because his compiler treated the two
as the same whereas mine doesn't), I assumed the basic algorithms
had been tested before posting. I guess I assumed too much. I never
did a complete line-by-line examination of his code to make sure it
looked correct, although now I did a line-by-line browse of it just
to see if anything else was obviously questionable, as well as to
find that troubling line of code again and see if it was the only
case of that particular problem.
So operator precence fooled Peter, and fooled me too, and Peter
didn't bother to unit-test each line of his code, and I just
assumed he had done so before posting his code to the net for
others to use. When I write code, I unit test *every* line of code,
even the most trivial of things, just to make sure I didn't make
some really really stupid typographic error, before I go on to the
next line of code. In lisp that style of developing code comes
totally naturally without any pain. In c it's a royal pain, which
is one of many reasons I hate to write software in c. For an actual
example of how I develop code with line-by-line unit testing, see:
<
http://www.rawbw.com/~rem/HelloPlus/CookBook/CookTop.html#stru>
(From the table of contents, in chapter 2, the section "Overall
structure of a program")
then search for the paragraph that begins:
Here's my preferred way to develop lisp software: Bottom-up overall,
input-forward within each level, unit-test each line of code before
incorporating it into a block of code, unit-test the completed block
before building a function around it, unit test the resultant function
before moving on to start work on the next. ...
and read the annotated transcript that follows.
<OFF-TOPIC>
There are a number of ways to avoid that; some of them may not be
available to you, depending on the resources to which you have access.
If you're able to set up your own web server, ...
Not available to me. No money to lease office space and purchase
equipment, nor to lease space on a commercial server farm.
If that's not possible, and all you can do is install your code in
cgi-bin, you can try installing it with a name that nobody is likely
to stumble across. You can exercise the code because you know its
name, but nobody else can.
But I'll be incrementally adding to existing CGI application, and
it's a royal pain to make a complete copy of everything (actual
program modules on cgi-bin, Web page with forms for exercising it
in GET and POST mode), and even if I do all that, I still have the
task of folding everything back into the main files, during which
there's a "flag day" when a mix of old and new stuff is
inconsistent. Since this isn't a major commerical service like the
Google search engine with millions or even thousands of users, I
consider it reasonble that new stuff is simply installed directly
online with a suitable warning for the zero or one users who happen
to bump into it during the few minutes it takes to complete the CGI
interfacing of the new module I already got debugged in a stdio
test rig. If I thought I had more than two users during any one
day, of which there was a good chance one of them would encounter
the temporary under-construction state, I might reconsider. At
present I have a couple other much more valuable services which
each gets used by somebody other than myself only about once in two
to six months.
Have you personally *ever* tried one of my CGI applications and
encountered a server abort, or obviously truncated output, because
the program crashed at the start (before transmitting the
CGI-MIME-type header) or in the middle respectively, because I had
just installed something new and it had a horrible bug? Have you
even see it produce obviously partial new output, where each time
you'd refresh it'd show a little bit more as I added line by line
of new code at the bottom? Has anyone reading this thread
encountered such work-in-progress ever?
If you have questions about CGI, try asking them in
comp.infosystems.
www.authoring.cgi.
I don't have any such questions at the present. But if and when I
ever decide to generate cookies, I might ask there, thanks for the
pointer.
More reply later...