Why can't SBCL determine the upgraded-array-type of elements of a string at compile-time?

87 Views Asked by At

I'm finding that SBCL (2.4.0, on x86-64 Linux) is having trouble optimizing character accesses in strings. The following code

(compile 
 nil 
 '(lambda (s)
    (declare (optimize (speed 3))
             (string s))
      (if (< 3 (length s))
        (char s 3))))

Gives the following warning when run:

; in: LAMBDA (S)
;     (CHAR S 3)
; 
; note: unable to
;   optimize
; because:
;   Upgraded element type of array is not known at compile time.

The warning goes away with a simple-string declaration. My question is, why does this happen? If I run (upgraded-array-element-type 'character) I get character. What about that isn't known at compile time? I'd obviously like to allow the user to use strings with fill pointers without giving up on an optimization, but mostly I'm just confused.

1

There are 1 best solutions below

1
ignis volens On

Nothing should not be be known at compile time I think. Even in code like

(defun foo (x)
  (declare (type string x))
  (function-which-might-adjust-x x)
  (char x 3))

Then adjust-array is constrained:

Element-type specifies the type of the elements of the resulting array. If element-type is supplied, the consequences are unspecified if the upgraded array element type of element-type is not the same as the actual array element type of array.

So it can't change the upgraded element type (and SBCL doesn't allow this as an extension).

So the upgraded array element type of s is, and remains, character.

I would ask the SBCL maintainers about this because it sounds like a deficiency in the compiler.