Preprocessor
Objectives
• Describe preprocessor commands
– syntax – common use
2
Preprocessing
• C# offers preprocessing – first stage of translation – performed by the compiler – evaluates preprocessor directives • The term preprocessor is historical – comes from the C/C++ tradition – preprocessor was separate program that ran before compiler
3
Preprocessor directives
• Available preprocessor directives
– #define – #undef – #if – #else – #elif – #endif – #line – #warning – #error – #region – #endregion
4
Basic syntax
• Preprocessing directive must be only statement on a line
– leading whitespace ok
leading whitespace
static void Main() {
#if Logging
...
}
5
Creating symbols
• Can create conditional compilation symbol – syntax: #define followed by symbol – must go at beginning of file – applies only to that file – ok to define same symbol more than once
create symbol
#define Logging
...
6
Compiler option
• Can use compiler option to create symbol – syntax: /define: followed by symbol – applies to all files in compilation command
use compiler option
C:\> csc /define:Logging MyApplication.cs
7
Symbol states
• Symbols have only two states
– defined – undefined
• States correspond to Boolean values
– defined = true – undefined = false
symbol now defined, has value true
#define Logging
...
8
Removing symbols
• Can remove symbol definition
– syntax: #undef followed by symbol – must go at beginning of file – applies only to that file – ok if symbol is not defined – useful to turn off symbol created with compiler option
remove symbol
#undef Logging
...
9
Testing symbol
• Several options for testing symbol status
– #if ... #endif – #if ... #else ... #endif – #if ... #elif ... #endif
• Boolean value of symbol used in test
– true = guarded code passed to next stage of compilation – false = guarded code eliminated
static void Main() {
#if Logging
code included only if symbol defined
Console.WriteLine("enter main");
#endif
}
10
Preprocessing expression
• Symbol test can be logical expression
– available operators: ! == != && || – parentheses can be used to group sub-expressions
test for not defined
#if !Logging
both must be true
...
#if Logging && Debugging
...
both must have same value, either true or false
#if Logging == Debugging
...
11
Controlling line number and file name
• Control line and file reported by compiler with #line
– #line number - change line – #line number "filename" - change line and filename – #line default - restore true line numbers and filenames
class Test {
report line numbers counting from 1
override line and file
restore accurate reporting
static void Main() {
#line 1 ... #line 5 "Source.cs" ... #line default ...
}
}
12
Diagnostic directives
• Can generate compile time warnings and errors
– #warning – #error
warning
#if FinalReview
#warning Recent change: updated 07-Nov-03 by MAT
#endif
error
#if Logging && MaximizePerformance
#error Turn off logging to maximize performance
#endif
13
Regions
• Create logical group with #region and #endregion
– have no effect on meaning of code – can supply name for region – can be convenient for programmer – can be read by development tools
class Stock {
fields
#region Private fields private string name; private double price; private int shares;
#endregion
constructors