|Do you know where your variables are?|
If you find them useful, then nothing I (or anyone) could say would nor should stop you from using them.
Personally, I don't feel that they were worth the effort of deriving, and worse, they can (and are) misused and so become dangerous. I have tried to explain my reasons why I feel this way.
Obviously, I can also find clues in reported problems, but isn't that just another metric?
Yes it is, but it is repeatable and comparable. If you have two projects/sites/customers or if the program is widely used, even two countries, then both the expectation and practice is that assuming other factors (number of users, programs runs, volumes of data etc.) are roughly equal, then you will get a similar number of error reports from both groups of users. And after maintanence, you should be able to measure the the drop in error reports.
Whilst LOCs may give you an indicating of how big the code is, it gives you no indication of anything beyond that. The code could be easy to maintain, or never need maintainance. Equally, a short module could be a nightmare. Most of the other numbers are similar. They measure something, but deriving meaning from them is almost impossible.
Code complexity is different and worse. It attempts to heuristically derive meaningful numbers for a specific purpose. That of allowing some judgement to be made about the quality or complexity of a module without inspecting the code. And that is where the numbers become not just almost meaningless, but dangerous as well.
Giving an absolute number for "compexity" is meaningless. "It's complexity is 50!". 50 what? Is 100 twice 50? Is there some cutoff point, 100 or 500 at which code is "too complex"? Obviously these questions are rhetorical. Complexity is relative, and the numbers can only be used comparatively.
The problem is that the number does say anything about (or make any consideration of) the complexity of the problem being solved. As I said somewhere above, you cannot reduce the complexity of the problem by measuring the complexity of the solution. Beyond more bad anologies, the only way I can substantiate this claim is by example.
Two pieces of code that set out to, and achieve, solving the same problem. They are written in the same language by two reasonably competent programmers.
Prog1 has (approx): 70 LOC; 7 FP; 4 loops; 6 branch points.
Prog2 has (approx): 60 LOC; 1 FP; 2 loops; 4 branch points.
Source code analysis of these two programs would completely miss the complexity (and the maintainance nightmare) inherent in one of them. (hint:mine).
Examine what is said, not who speaks.
Silence betokens consent.
Love the truth but pardon error.