Skip to main content

How to Resolve Error "CS1040: Preprocessor directives must appear as the first non-whitespace character on a line" in C#

The Compiler Error CS1040 is a syntax formatting error. The message reads: "Preprocessor directives must appear as the first non-whitespace character on a line".

In C#, preprocessor directives (commands starting with #, such as #region, #if, #define, #pragma) obey strict positioning rules. They do not have to be at the very beginning of the line (indentation with spaces or tabs is allowed), but they must be the first meaningful content on that line. You cannot place code, comments, or other text to the left of the hash symbol #.

This guide explains how to correctly format these directives.

Understanding Directive Positioning

The C# preprocessor scans files line by line. When it encounters a #, it expects that to be the start of an instruction.

  • Allowed: #region Settings (Spaces/Tabs before # are fine).
  • Not Allowed: int x = 1; #region Settings (Code before # is invalid).
  • Not Allowed: // Start #region Settings (Comments before # are invalid).

Scenario 1: Code Preceding the Directive

This usually happens when a developer tries to be concise by putting a region start or an #endif on the same line as a closing brace or a statement.

Example of error

Placing a directive immediately after a statement.

public class User
{
public string Name { get; set; }

// ⛔️ Error CS1040: Preprocessor directives must appear as the first
// non-whitespace character on a line.
// You cannot put '#region' after the semicolon.
public int Age { get; set; }; #region Methods

public void Save() { }

#endregion
}

Solution: Use a New Line

Move the directive to its own line. Indentation is permitted.

public class User
{
public string Name { get; set; }
public int Age { get; set; }

// ✅ Correct: The directive is on its own line.
// Whitespace (indentation) before the '#' is allowed.
#region Methods

public void Save() { }

#endregion
}

Scenario 2: Comments Preceding the Directive

While you can put comments after a directive (e.g., #endif // End Debug), you cannot put comments before it. The preprocessor sees the // or /* as the "first non-whitespace characters," which violates the rule that the directive must come first.

Example of error

Trying to describe the directive before writing it.

public class Program
{
static void Main()
{
// ⛔️ Error CS1040: The comment starts the line, not the directive.
/* Debug Mode check */ #if DEBUG
Console.WriteLine("Debug");
#endif
}
}

Solution: Reorder or Move Comments

Move the comment to the previous line or place it after the directive.

public class Program
{
static void Main()
{
// ✅ Correct: Comment is on the previous line.
/* Debug Mode check */
#if DEBUG
Console.WriteLine("Debug");
#endif

// ✅ Correct: Comment is AFTER the directive.
#if DEBUG // Debug Mode check
// ...
#endif
}
}
note

Why is indentation allowed? C# allows whitespace before the # so that you can indent your preprocessor directives to match the nesting level of your code (e.g., inside a class or method). The compiler ignores the spaces/tabs and successfully finds the #.

Conclusion

CS1040 ensures the preprocessor can cleanly identify commands.

  1. Check the Left Side: Look to the left of the # symbol.
  2. Remove Text: Ensure there is nothing there except spaces or tabs.
  3. Move Code: If you have code or comments on the same line, press Enter to move the directive to a fresh line.