Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

0002378

Suspended
Original poster
May 28, 2017
675
671
How to find dead Swift code using XCode ? Mine is version 8.3.3, if that matters.

I would like to remove unused functions and classes/structs. My XCode does find unused variables/constants, but doesn't find anything else unused.

I tried this, with no luck:

XCode-deadCode.png
 
Last edited:
It depends on when the dead code analysis happens. Dead code stripping for optimization purposes happens during link time, which the LLVM checks should work against that you see there. Doesn't look like classes are part of what it will strip out, but when doing this at the linker step, that's actually expected.

A struct or class at its core is a description of the data structure, and functions that are associated with that data structure. C++ and Swift both do this. Direct access is inherently inlined in the function doing the access. So if I have a pure data struct, there's no actual code emitted associated with the type. It's all emitted as direct memory accesses in the code. This means that a linker can't actually tell what isn't used at that level. If I have functions associated with my type though, those functions can be determined to be dead or not, so you will get warnings for that from LLVM.

I get what you want to do, which is let the toolchain tell you what cruft you have sitting around so you can prune it a bit more aggressively. But what the dead code analyzer does in this case is more focused on blocks of code that it can decide to strip from the final binary at link time to keep the binary size down. So there's a bit of a mismatch in goals, and what can be detected at the appropriate time. The warnings are there mostly as a convenience.
 
  • Like
Reactions: 0002378
Thanks Krevnik.

I appreciate the info but I'm looking at it simply from a source code cleanup perspective, regardless of optimization or what happens behind the scenes.

The Eclipse IDE for Java, which I used for many years, readily tells you which functions/classes, etc are not used, and I expected the same from XCode. Simple as that.

I just want to put my Delete key to work and watch all that excess code fall to the floor like hair falling to the floor at a salon :D

(BTW, thanks for all your help, a few months ago, with my other questions, e.g. audio buffering/playback, task scheduling, and stuff ... that audio player app has come along nicely, and the buffering logic has been rock solid ever since ! Never failed. I gave you an honorable mention in my thread about the app, a while ago :D)
 
Last edited:
Oh, I hear you. I wish it was a bit easier too.

The catch here is that what happens behind the scenes helps determine what the IDE can do. This sort of dead code analysis pretty much never uses static code analysis. It's simpler to use the output of the compiler to do it, and if you do want to analyze the code by hand, you are pretty much writing a good chunk of a compiler to do it in the first place. Java's interesting because of what is kept in the .class files. A good chunk of info on the type is preserved in the file, making it pretty nice for this kind of analysis. Swift is more like C++ where the intermediate outputs (.o/.a) don't actually contain any type information in them, just symbols for the linker.

Maybe in time we can see something more along these lines using Whole Module Optimization, where swiftc actually can see the whole module at the same time, and also has the type information. Who knows.

Glad to hear the buffering works well.
 
  • Like
Reactions: 0002378
Run static analyzer. It’ll look for code that never gets called.

Thanks. I just tried that (Product > Analyze). It reported that it succeeded ... i.e. no errors/warnings, despite 3 unused functions I just added to the code.

From what I read online, and also from the project settings section (as in the screenshot in my original post in this thread), it looks like Static Analyzer ignores or is incapable of analyzing Swift code :(

Thanks anyway.
 
  • Like
Reactions: Ironman226
AppCode IDE has tonnes of functions to help you with this. Xcode does not, as far as I am aware.
 
  • Like
Reactions: 0002378
Thanks. I just tried that (Product > Analyze). It reported that it succeeded ... i.e. no errors/warnings, despite 3 unused functions I just added to the code.

From what I read online, and also from the project settings section (as in the screenshot in my original post in this thread), it looks like Static Analyzer ignores or is incapable of analyzing Swift code :(

Thanks anyway.
Oh wow I didn’t know this was still Obj-C only. That’s crazy. Sorry to waste your time.
 
Oh wow I didn’t know this was still Obj-C only. That’s crazy. Sorry to waste your time.

Oh no worries, it was worth a try and it only took 10 seconds :)
[doublepost=1510535311][/doublepost]I understand that analyzing symbols is not trivial, but I don't see why it can't at least do simple text-based reference matching ? It should be able to detect the most simple cases of symbols not being used, regardless of whether the code is written in Swift, Obj-C, Japanese, or Russian.

What I mean is ... let's say there's a class called "MyClass" and if I do a simple text search for MyClass in my project, there are no results (other than where it is defined), it could indicate that it is not being used. So, the XCode analyzer could at least do a text search, and provide a warning, not with certainty, but pointing to the possibility that a symbol is not being referenced. The developer could then investigate the warning and determine if the warning is false or not.

Why would this be a good way to point out potentially unused classes/functions ? Because, that is exactly how I find dead code myself :D I do a very simple text search, and in most cases, if not all, it works :)

"Class "MyClass" possibly not being referenced"
 
Last edited:
I understand that analyzing symbols is not trivial, but I don't see why it can't at least do simple text-based reference matching ? It should be able to detect the most simple cases of symbols not being used, regardless of whether the code is written in Swift, Obj-C, Japanese, or Russian.

Yup, and it works until it doesn't. It can certainly be done, but no toolchain worth their salt will include it. I've spent some time working on toolchains and the general rule has been that your stuff has to be bulletproof. Developers will accept ~80% success on their own tools that they run infrequently, but not from stuff included in the SDK.

A couple things I can think of that make this approach annoying, and require that I be syntax-aware, or even require developer intervention to get good data:
  • NIBs reference code, and are many times the "root reference" into a piece of code.
  • Libraries and Plugins don't have a "root reference" in the same way an application with main() does. In the case of Libraries, there are headers, but in the case of Plugins, there may only be an arbitrary Info.plist entry (or multiple ones) defined by the developer who created the plugin interface.
  • Comments require syntax-aware processing, rather than text processing.
  • Overloaded functions require more syntax-aware processing to disambiguate which overload is used, and which isn't.
So while it works for your workflows, it breaks down in others, which is why I would hesitate to spend resources solving the problem this way in a toolchain like Xcode, GCC, etc.

Oh, and there's one last thing I've forgotten about Swift/Obj-C that makes it hell on dead code analysis: the Objective-C runtime. Because of how it works and the fact that any random chunk of code can reference types and methods by name, you can't really strip classes that wind up in the runtime. The irony here is that this both enables tools like NIBs and plugins to work, and throws a wrench into dead code analysis at the same time. Swift is only partially vulnerable to this problem, but any type that is marked with @objc or has methods marked @objc would still be vulnerable, which happens to include any sort of subclassing you do, or types that have to interact with UIKit/AppKit (delegates/etc). KVO in Objective-C makes dead code stripping cry pretty hard.
 
Yup, and it works until it doesn't.

I would like to share with you an alternative perspective, expressed as an analogy. And, I say this with the utmost respect for the depth of your knowledge.

Let's say I'm really excited about the new 2018 Toyota Camry. And I love everything about it, but I find out that navigation is not offered on the trim that I'm interested in. And, this really disappoints me. So, I go to Toyota customer service and ask them, "How come you don't offer navigation on this Camry trim ?" And, in return, I get a 100 page technical manual explaining the gory intimate details about the dashboard electronics being laid out in such a manner that fitting a navigation in there was just not feasible in the end.

Do you expect me, the customer, to be satisfied with that answer ? Or would you expect me to respond with, "I don't care about your technical reasons. All your competitors have navigation. You should have one too."

:)

Customers look at products as black boxes. They don't care about the technical reasons why something is possible or not, much less should they need to.

As a programmer, I am a user/client/customer of XCode, and I don't give a rats ass about their reasons for not being able to implement a feature that I think is quite reasonable to expect in such a full-fledged IDE ... technical reasons be damned.

Now, of course, I don't have to use XCode; I can switch to another IDE (if there is one for Swift). But, you get my point (I hope) :)
 
Last edited:
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.