S
santosh
jaysome said:santosh said:jaysome wrote:
On Mon, 24 Mar 2008 17:46:01 -0500, CBFalconer wrote:
Peter Michaux wrote:
I am thinking of a few situations that involve iterating over a
structure (e.g. array, linked list, tree) and doing "something"
to each node. The structure may be a parse tree where each node
is a struct representing a different kind of language
statement. The structure may be a list of allocated objects
that each require a different destroy function to be called for
garbage collection.
How would you handle these heterogeneous structures in C?
I'd say, probably, the program is fundamentally misdesigned for
C. A parse tree definitely makes sense in a language such as
Lisp. In C, the parsing is better expressed as a hierarchy of
mutually recursive functions.
Are there not thousands of language compilers and interpreters
that are written in C and produce parse trees? Are they all
fundamentally misdesigned for C?
Take a look at hashlib. It was originally designed with the idea
of use in compiler symbol table generation (note the ease of
opening, closing
and nesting tables). Purely standard C, so no portability
problems.
I think hashlib has portability problems, insofar as it does not
compile without error with gcc on 64-bit Ubuntu Linux 7.10.
jaysome@ubuntu:~/downloads/hashlib$ uname -a Linux ubuntu
2.6.22-14-generic #1 SMP Thu Jan 31 23:33:13 UTC 2008 x86_64
GNU/Linux
jaysome@ubuntu:~/downloads/hashlib$ make cc -W -Wall -ansi
-pedantic
-O2 -gstabs+ -c -o hashlib.o hashlib.c cc -W -Wall -ansi
-pedantic
-O2 -gstabs+ -c -o cokusmt.o cokusmt.c In file included from
cokusmt.c:59:
cokusmt.h:9:5: error: #error System long word size not suitable for
cokusMT
make: *** [cokusmt.o] Error 1
In <limits.h>
/* Maximum value an `unsigned long int' can hold. (Minimum is 0.)
*/
# if __WORDSIZE == 64
# define ULONG_MAX 18446744073709551615UL # else
# define ULONG_MAX 4294967295UL
# endif
__WORDSIZE is 64 on my machine, and this is acceptable by both the
C90 and C99 C standards.
Well the README file that comes with hashlib says that "cokusmt.c"
and it's associated header are purely to ensure that regression test
will function on any system, though as you say, the files themselves
do not compile on systems where ULONG_MAX is not 4294967295.
Also the README file notes that under DJGPP, Cygwin or Linux the
only command needed to compile the package should be:
make hashlib
However this fails over here with the following error message:
$ make hashlib
cc -W -Wall -ansi -pedantic -O2 -gstabs+ -c -o hashlib.o
hashlib.c
cc hashlib.o -o hashlib
/usr/lib/gcc/i486-linux-gnu/4.0.3/../../../../lib/crt1.o: In
function `_start':../sysdeps/i386/elf/start.S:115: undefined
reference to `main' collect2: ld returned 1 exit status make: ***
[hashlib] Error 1 $
I think his Makefile is specific to DJGPP/Windows.
Also for a package that is frequently advertised as being pure ISO C,
he should probably rethink the following statement in line 388 of
hashtest.c:
fflush(stdin);
Good catch.
I suspect that, based on the code:
if (0 == (i % 20000)) {
printf("\r%lu inserted", i);
fflush(stdin);
}
it should be:
fflush(stdio);
Yes, and he should probably fix his makefile so that it doesn't try to
produce an executable for the 'make hashlib' invocation.
<concerning undefined behaviour>
AFAIK fflush(stdin) does not clear the stdin buffer on at least
glibc/Linux, so if code must use fflush(stdin), it has to be guarded by
#ifdefs, so that it is not compiled in for platforms that do not
implement it.
This is true for UB in general, since many cases of UB are actually
pretty well defined _for_ a particular implementation, but unlike
implementation defined behaviour, there is no requirement that it be
so. Thus portable code must at the very least conditionally compile
code invoking UB only under implementations that do define it as
desired.