cc-mode is about 20k SLOC of Emacs Lisp responsible for setting up major modes for C, C++ and other sufficiently C-like languages. To put this into perspective, ruby-mode is 2k SLOC and text-mode about 200 SLOC. Surely there must be clever and not so clever things included into it!
And indeed, while attempting to figure out why indentation went wrong for csharp-mode by squinting hard at c-get-syntactic-indentation, I’ve stumbled upon a most curious variable, c-syntactic-element:
(defun c-get-syntactic-indentation (langelems) ;; ... (let ((indent 0) anchor) (while langelems (let* ((c-syntactic-element (car langelems)) (res (c-calc-offset c-syntactic-element))) ...))))
Naturally I tried inspecting its value with good ol’ F1 v:
c-syntactic-element is void as a variable. ... This is always bound dynamically. It should never be set statically (e.g. with `setq').
Well, would you look at that. This variable was defined, but never initialized. In fact, its value is only non-void when dynamic binding is used to bind it throughout the invocation of whatever ends up calling c-get-syntactic-indentation. Usually you’d only have a docstring if you were to use defvar which requires an initial value, but this requirement was cleverly circumvented by directly adding a docstring property to the symbol of the variable after its definition.
I guess this is done to avoid passing the value explicitly, but it still annoys me that I need to instrument a function to figure out the value of a variable it relies on. Worse, this hack would most likely break if lexical binding were to be enabled for cc-mode and turns any meaningful (read: not involving subtle and less subtle breakage) refactoring of the code into a surprisingly difficult task. The only place I can spot where c-syntactic-element is dynamically bound is said function, but it is not clear how calling it affects the number of other functions using that variable.
I’m sure a set of specific helpers is included to simplify debugging, but it still annoys me when something from the official toolbox is rendered unusable.