help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: How to avoid compiler warning `unused lexical variable' for `dolist'


From: Stefan Monnier
Subject: Re: How to avoid compiler warning `unused lexical variable' for `dolist' or `dotimes'?
Date: Fri, 08 Jan 2021 02:10:58 -0500
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux)

>>     (dotimes (i length plist)
>>       (setf plist (plist-put plist (intern (elt columns i)) (elt values 
>> i))))))
> And here is the original warning:
>> rcd-db.el:841:1: Warning: Unused lexical variable ā€˜iā€™
> Jean Louis actually is using the variable i, it's not unused.

There are 2 places where `i` is introduced:
- one around the body of the loop
- another around the 3rd arg used as return value.
To see it you need to macroexpand the `dotimes`:

    (dotimes (i length plist)
      (setf plist (plist-put plist (intern (elt columns i)) (elt values i))))
=>
    (let ((--dotimes-limit-- length)
          (--dotimes-counter-- 0))
      (while (< --dotimes-counter-- --dotimes-limit--)
        (let ((i --dotimes-counter--))
          (setf plist (plist-put plist (intern (elt columns i)) (elt values 
i))))
        (setq --dotimes-counter-- (1+ --dotimes-counter--)))
      (let ((i --dotimes-counter--)) plist))

Clearly, this is not the only way to define the macro, but it's a valid
way (according to the Common Lisp definition, for example).
Now you hopefully see on the last time that `i` is indeed defined but
not used.  This is the code which the compiler sees.

You won't get this warning if you do:

    (dotimes (i length (progn (ignore i) plist))
      (setf plist (plist-put plist (intern (elt columns i)) (elt values i))))
or
    (dotimes (i length)
      (setf plist (plist-put plist (intern (elt columns i)) (elt values i))))
    plist

I'm not trying to argue that the byte-compiler warning here is
a feature, but in general the "unused var" byte compiler warnings are
very useful (especially when converting code to `lexical-binding`) and
while in this case it's kind of spurious it's very easy to change the
code so as to avoid the warning (and the resulting code is also more
efficient and arguably more readable for people not used to this 3rd
arg of dotimes/dolist), so this is not a very compelling motivation to
improve the warning machinery.

There can be situations when using `pcase` where the byte-compiler will
tend to emit similar warnings and these are more problematic because it
can be hard to rewrite the code to avoid the warning.

I haven't yet figured how to make it possible to avoid those warnings,
so in the `pcase` macro I added extra hacks to try and avoid introducing
bindings that aren't used, which basically silence those warnings, with
the downside that you won't get the warning even in the case where it's
really warranted.

> You could argue that the warning should be "The three element version of
> dotimes is discouraged".  But I can't see how you can argue that the
> warning is right, since i is used.

The var-use analysis takes place after macro expansion.

This is not specific to this warning, tho: all warnings suffer from
false positives, almost by definition.  If we knew for sure that the
warning points to a real "bug" we could turn it into an error.


        Stefan




reply via email to

[Prev in Thread] Current Thread [Next in Thread]