Hi Tomas,

> : (cadr (cons 1 2))
> Segmentation fault (core dumped)

Yes, this is a known bug. In fact, it was a deliberate design decision.

There is always a trade-off between runtime-checks and performance.
PicoLisp tries to walk along the line of doing runtime checks for
typical errors, but not more than necessary.

The core dump arises because a number is accessed illegally. If you try

   : (car 1)
   !? (car 1)
   1 -- List expected

the error is caught. The same happens for

   : (car (cdr (1 . 2)))
   !? (car (cdr (1 . 2)))
   2 -- List expected

So those functions check their *direct* arguments, but not the whole
traversed chain. If you look at the definition of 'cadr'

   any doCadr(any ex) {
      any x = cdr(ex);
      x = EVAL(car(x));
      return cadr(x);

you see the check with 'NeedLst()', and then the call of the Macro 'cadr()'.

'cadr(x)' expands to x->cdr->car, and cadddr(x) to x->cdr->cdr->cdr->car.

It would be quite some overhead to expand this with a check between each
pointer dereference, which at normal program operation (if the code was
tested at least once) would never find an error.

In a nutshell, if you want to be sure to catch such errors, simply use
(car (cdr (x))) instead of (cadr x).

There are plenty of other possibilities to produce a core dump ;-)
Just try, say

   : (setq a 1)
   -> 1
   : (a) 
   Segmentation fault

But I think this is acceptable in return for other advantages like
simplicity and speed.

> Is this the right place to report bugs or is there any bug tracking
> system for picolisp?

No, here is just fine. That's why we started this mailing list.

- Alex

Reply via email to