Console.WriteLine('.');
#endif
}
}
Figure 3-16 shows the output when the DEBUG
symbol is defined using the /define
compiler option.

Figure 3-16
The #error
preprocessor directive lets you generate an error. Consider the following example:
for (int i = 1; i <= num; i++) {
//---sum up all odd numbers---
if (i % 2 == 1) {
sum += i;
#if DEBUG
#warning Debugging mode is on
Console.WriteLine('i={0}, sum={1}', i, sum);
Console.WriteLine('sum={0}', sum);
#else
#warning Default mode is on
Console.WriteLine('.');
#endif
}
}
Here, if the NORMAL
symbol is defined, an error message is shown and the statement defined within the conditional directive is ignored. Figure 3-17 shows that when you define the NORMAL
symbol, the error message is displayed and the compilation is aborted.

Figure 3-17
#line
The #line
preprocessor directive lets you modify the compiler's line number and (optionally) the file name output for errors and warnings.
The #line
preprocessor directive is injected in the following example. The highlighted code indicates statements that will cause the debugger to issue warning messages:
1. using System;
2. using System.Collections.Generic;
3. using System.Linq;
4. using System.Text;
5.
6. namespace TestDefine
7. {
8. class Program
9. {
10. static void Main(string[] args)
11. {
12. #line 25
15. Console.WriteLine('Line 1'); //---treated as line 27---
16. #line hidden //---treated as line 28---
17. Console.WriteLine('Line 2'); //---treated as line 29---
18. Console.WriteLine('Line 3'); //---treated as line 30---
19. #line default
21. Console.WriteLine('Line 4'); //---treated as line 21---
22. #line 45 'Program1.cs' //---treated as line 22---
24. Console.WriteLine('Line 5'); //---treated as line 46---
25. Console.ReadLine(); //---treated as line 47---
26. }
27. }
28. }
The line numbers are for illustration purposes and are not part of the program.
The four highlighted lines are numbered 13, 14, 20, and 23. When you build the program in Visual Studio 2008, the lines reported are 25, 26, 20, and 45 (see Figure 3-18).

Figure 3-18
Let's take a look at the #line
directives in the example program:
□ #line 25
means that you want to modify the line number to use the specified line number (25 in this case) instead of the actual line number of the statement in error. This is useful if you need to assign a fixed line number to a particular part of the code so that you can trace it easily. Interestingly, the next line will continue from 25, that is, the next line is now line 26. This is evident from the warning message for the char c;
line.
□ #line default
means that the compiler will report the actual line number.
□ #line 45 'Program1.cs'
means that you want to fix the line number at 45 and specify the name of the file in error (Program1.cs
in this case). An example usage of it would be that the statement in error might be a call to an external DLL and by specifying the filename of the DLL here, it is clearer that the mistake might be from that DLL.
What about the #line hidden
statement? That preprocessor directive indicates to the debugger to skip the block of code beginning with the #line hidden
preprocessor directive. The debugger will skip the line(s) until the next #line
preprocessor directive is found. This is useful for skipping over method calls that you are not interested in (such as those not written by you).
Interestingly, you can replace the #line hidden
preprocessor directive with #line 16707566
(0xFeeFee) and it will still work correctly.
#region and #endregion