defined operator placed in a macro replacement list

ID

objectivec.maintainability.defined_operator_misuse

Severity

low

Remediation Complexity

medium

Remediation Risk

medium

Remediation Effort

medium

Resource

Preprocessor

Language

Objective-C

Description

Reports a defined operator inside the replacement list of a #define, so that it reaches a controlling expression only by being macro-expanded into one. This rule is about where the operator is placed; a defined written directly in an #if or #elif with a non-standard operand is reported by defined-operator-nonstandard.

Rationale

The standard says that if the defined token comes out of a macro expansion during the evaluation of an #if, the behavior is undefined. Toolchains split on it: some evaluate the operator anyway, some treat the expanded defined as an ordinary identifier and replace it with 0, which turns the condition false and quietly drops the guarded code from the build. Both outcomes compile without a diagnostic, so a project that works on one compiler can lose whole features on another.

The following code illustrates the pattern detected by this rule:

// FLAGGED: defined operator placed in a macro replacement list
#define XY_HAS_DEBUG defined(DEBUG)

Remediation

Write the defined directly in the #if or #elif that needs it. Where the condition is shared, express the flag as a plain 0/1 macro chosen inside #if defined(…​) - for example #if defined(DEBUG) then #define XY_HAS_DEBUG 1, #else then #define XY_HAS_DEBUG 0 - and test that macro with #if XY_HAS_DEBUG.

Configuration

This detector does not need any configuration.

© 2026 Xygeni. All rights reserved