4

(This is a bit of an X-Y problem, but I decided to ask the question that interests me, rather than the one I strictly need at the moment.) I know the various modern JavaScript engines have dead code eliminators and other means to get rid of code that has no effect or side effect, but how do you identify and/or compose such code?

The Wikipedia article on Dead code elimination gives one straightforward example of unreachable code, that is, code that happens after the unconditional return statement in a function. But can I count on the modern, major JavaScript engines to eliminate such code? For example, will Rhino or V8 eliminate this code?

function (foo) {
    return;
    return foo;
}

function (foo) {
    foo = foo;
}

and what about no op functions?

(function () {}(foo));
jQuery.noop(foo);

All of these examples fool JSHint, and while JSLint catches the weird assignment foo = foo, you can still trick it quite easily with the noops or a pair of variables:

function (foo) {
    var bar = foo;
}

If they can trick the static code analyzers, will they trick the engines themselves?

Short of closely examining the source of all the different JavaScript engines, is there any way to identify and/or construct the kind of code that will surely be eliminated before the program is ever run, and should it be considered a bug if such code is not elided, or is it merely a design choice?

Elliot B.
  • 17,060
  • 10
  • 80
  • 101
kojiro
  • 74,557
  • 19
  • 143
  • 201
  • What difference does it make whether the code is eliminated or not? (Where would it "go" if it were eliminated?) – Pointy Jan 19 '13 at 01:14
  • 1
    Note the dead code elimination is not *entirely* accurate in JavaScript due to hoisting of function declarations. – Matt Jan 19 '13 at 01:15
  • @Pointy into the annals of version control history? Or maybe, *just* maybe, I actually want to trick the static analyzer without tricking the engine. (Let's just say that some JavaScript linters don't recognize abstract methods for what they are, and complain about their signatures.) – kojiro Jan 19 '13 at 01:16
  • @Matt I thought of that, but if you declare a name and it never gets used in its scope, it's still dead code, no? `function () { return; var foo = 1; }` – kojiro Jan 19 '13 at 01:18
  • There are lots of ways of declaring code such that a linter won't be able to tell whether it's dead code. A conservative linter will emit a warning, and any *decent* linter will have ways for you to explicitly mark such blocks. If you can simply tell the linter to shut up when you know better than it does whether code is dead or not, why not just do that? – Pointy Jan 19 '13 at 01:20
  • ... and I think you're right about this being an X-Y question :-) – Pointy Jan 19 '13 at 01:22
  • @Pointy I would, if I could still sanely tell the linter not to shut up other times. But let's not get bogged down in the X, because I'm not actually looking for an answer there. – kojiro Jan 19 '13 at 01:23

1 Answers1

2

Finding dead code in JavaScript is a different beast than finding dead code in other languages like C++. For example, You can compile C++ to detect unreachable code, but obviously that's not possible with JavaScript.

The example of dead code you've given function () { return; var foo = 1; } is far less likely to occur than an event handler assigned to an HTML element that no longer exists on the page. No automated dead code analyzer could detect the latter.

What you can do is use a code coverage tool during your test runs and look for unused lines. You just have to ensure your test scripts are very thorough.

Elliot B.
  • 17,060
  • 10
  • 80
  • 101
  • 1
    You can easily write dead code in C++ the compiler can't eliminate. Check out Alan Turing. Its just easier to do in Javascript. – Ira Baxter Jan 19 '13 at 01:22
  • 2
    @IraBaxter I don't disagree. I'm just pointing out that with C++ you do have some automated tools for detecting dead code, but with JavaScript you don't. – Elliot B. Jan 19 '13 at 01:25