Function or variable defined in a header rather than declared

ID

objectivec.correctness.definitions_in_headers

Severity

low

Remediation Complexity

medium

Remediation Risk

medium

Remediation Effort

medium

Resource

Header Hygiene

Language

Objective-C

Description

Reports a definition - a function with a body, or a variable with an initialiser - written at file scope in an Objective-C header. static, inline, NS_INLINE and extern forms are not reported, and neither is a plain declaration. The rule scans *.h only, because that is the only place the defect exists; a definition in the matching .m is exactly where it belongs.

Rationale

A header is textually pasted into every file that imports it, so a definition in one becomes a separate copy of the same external symbol in every translation unit that sees it. The second copy is a duplicate symbol link error, and because the header may well be imported by only one .m today, the build stays green until an unrelated file imports it months later and the failure surfaces far from the change that caused it. Precompiled headers and umbrella headers make that reach wider still. The trailing NSString *const kFoo = @"…"; in a public header is the usual Objective-C form of this.

The following code illustrates the pattern detected by this rule:

// FLAGGED: Function or variable defined in a header rather than declared
CGFloat XYCanvasAspectRatio(CGFloat width, CGFloat height) {
    if (height == 0.0) {
        return 0.0;
    }
    return width / height;
}

Remediation

Leave the declaration in the header and move the definition to the matching .m: extern NSString *const XYFoo; in the header, NSString *const XYFoo = @"…"; in the implementation, and a bare prototype instead of a function body. Where a small function must stay header-only for inlining, mark it static inline (or NS_INLINE), which gives each translation unit its own private copy instead of a competing external one.

Configuration

This detector does not need any configuration.

© 2026 Xygeni. All rights reserved