Conflicting OPTIMIZE declarations within a same "declarations block" unconservatively favor the last declaration of its kind.
Affects | Status | Importance | Assigned to | Milestone | |
---|---|---|---|---|---|
SBCL |
New
|
Undecided
|
Unassigned |
Bug Description
What I do:
(defun optimize-speed? (a b)
(declare (optimize (speed 0) (speed 3)))
(+ a b))
(optimize-speed? 1 2)
=> 3
What happens:
Execution proceeds without an error of any kind being thrown. The result is also "technically correct" (the best kind of "correct"!). But what happened to my conflicting declarations?? Let's ask sb-ext:
(sb-ext:
-| [...] SPEED = 3 [...]
(sb-ext:
-| [...] SPEED = 0 [...]
So, apparently the last specification for each OPTIMIZE quality overrides the preceding ones. Which is exactly what I'd expect, for example, for:
(defun optimize-speed? (a b)
(declare (optimize (speed 0)))
(locally (declare (optimize (speed 3)))
(+ a b)))
What I expected to happen:
I'll be the first to say that this behavior doesn't contradict the standard. From CLHS OPTIMIZE:
"The consequences are unspecified if a quality appears more than once with different values. "
But in the case where multiple conflicting OPTIMIZE declarations appear within a same "declarations block", as in the first example, I think the best behavior would be to signal an error at compile-time.
I think it's a very desirable property that most types of declarations within a same "declarations block" are "naturally" order-independent as a side-effect of their semantics. It's tragic to just barely lose this property for, as far as I can tell, no gain.
I also think such conflicting declarations are usually the result of programming errors (such as careless handling of declarations in macroexpansions). I can't really think of a scenario where someone would deliberately use this "feature", and also someone relying on such a feature would likely find a different behavior in other implementations. Maybe a quick test of how other implementations deal with this situation would be enlightening.
So, to sum up, I think conflicting OPTIMIZE declarations within a same "declarations block" should signal an error at compile-time. Else, the current behavior should be documented. I found no trace of this in the SBCL manual.
Here's a more complete test-case:
(defun optimize-speed? (a b)
(declare (optimize (compilation-speed 0) (compilation-speed 3)
(+ a b))
SBCL version: 1.0.42
uname -a: Linux dynamorph 2.6.32-27-generic #49-Ubuntu SMP Wed Dec 1 23:52:12 UTC 2010 i686 GNU/Linux
*features*:
(:SWANK :QUICKLISP :SB-BSD-
:SBCL :SB-DOC :SB-TEST :SB-LDB :SB-PACKAGE-LOCKS :SB-UNICODE :SB-EVAL
:SB-SOURCE-
:LARGEFILE :GENCGC :STACK-
:COMPARE-
:STACK-
:STACK-
:CYCLE-COUNTER :INLINE-CONSTANTS :MEMORY-
:OS-PROVIDES-
This is mostly a duplicate of https:/ /bugs.launchpad .net/sbcl/ +bug/310267