stride3d/stride · error · LexerException

Cannot redefine name 'defined'

Error message

Cannot redefine name 'defined'

What it means

addMacro() refuses to install any macro named 'defined' because 'defined' is the reserved operator used in #if expressions; redefining it would corrupt conditional-evaluation logic. The same check exists for macros created via define().

Solutions

  1. Remove the #define of 'defined' from the shader/header source
  2. Rename the macro to any other identifier
  3. Filter macro lists before calling addMacro to skip the reserved name

Example fix

// before
pp.define("defined", "1");
// after
if (name != "defined") pp.define(name, "1");
Defensive patterns

Strategy: validation

Validate before calling

if (macroName == "defined") throw new ArgumentException("'defined' is a reserved preprocessor operator");

Try / catch

try { pp.addMacro(m); } catch (LexerException e) { log.Error($"Rejected macro: {e.Message}"); }

Prevention

When it happens

Trigger: Calling preprocessor.addMacro(new Macro("defined"...)) or preprocessor.define("defined", ...) — typically via a #define defined ... line or programmatic macro setup.

Common situations: Ported C/C++ headers that (illegally) #define defined; generated code that emits macro tables blindly; users attempting to make 'defined' behave as a constant.

Related errors


AI-assisted analysis of stride3d/stride@96fad776d2 (2026-09-14). Data as JSON: /api/errors/00d1328b66eca15a. Report an issue: GitHub.

Appendix: source

Thrown at sources/shaders/Stride.Shaders.Parsers/CppNet/Preprocessor.cs:331

	 *
	 * @see #warning(int, int, String)
	 */
	protected void warning(Token tok, String msg) {
		warning(tok.getLine(), tok.getColumn(), msg);
	}

	/**
	 * Adds a Macro to this Preprocessor.
	 *
	 * The given {@link Macro} object encapsulates both the name
	 * and the expansion.
	 */
	public void addMacro(Macro m) {
		// System.out.println("Macro " + m);
		String	name = m.getName();
		/* Already handled as a source error in macro(). */
		if ("defined" == name)
			throw new LexerException("Cannot redefine name 'defined'");
		macros[m.getName()] = m;
	}

	/**
	 * Defines the given name as a macro.
	 *
	 * The String value is lexed into a token stream, which is
	 * used as the macro expansion.
	 */
	public void addMacro(String name, String value) {
		try {
			Macro				m = new Macro(name);
			StringLexerSource	s = new StringLexerSource(value);
			for (;;) {
				Token	tok = s.token();
                if(tok.getType() == Token.EOF)
					break;
				m.addToken(tok);

View on GitHub (pinned to 96fad776d2)