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
}
}
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.
- Check the Left Side: Look to the left of the
#symbol. - Remove Text: Ensure there is nothing there except spaces or tabs.
- Move Code: If you have code or comments on the same line, press Enter to move the directive to a fresh line.