Chapter 10
Compiler Error Messages
We will come across a large number
of errors that state Internal Compiler Error. These errors are extremely
dangerous as the compiler itself cannot figure them out. They fall under two
broad categories.
One, we may have made some dumb
mistake which the developers at Microsoft may have not even thought off, thus
confusing the compiler thoroughly.
Secondly, there could be a
genuine bug in the compiler.
Take your pick. The first error
number CS0001 is an internal compiler error. A catch all phrase for 'I do not
know what went wrong'.
Thus, the very first compiler
error number is thrown when the compiler is totally confused and doesn't know
how to react to the error. The compiler will resort to this error as the last
error before breaking down. Please understand the irony. The guys who wrote the
compiler could have made it the last error number but symbolically made it the
first.
After studying the different
programming languages developed so far over a period, we figured out that the
best way to understand more about any programming language is by placing
ourselves in the shoes of the sole person who wrote the language.
This person did not write the
language per se but a compiler through which he expressed his philosophy of the
language. Thus, the only way out is to understand the million error messages we
receive.
This process gets us into the
minds of a compiler, thus unearthing what it perceives is right and wrong with
our program. Thus, we have endeavored to sprinkle throughout our books every
error message the compiler can ever throw at us.
After CS0001, we realized that
there was no error message CS0002. Since the numerical part of the error number
is the only one that changes, we concluded that there can be a maximum of only
9999 errors that we can ever make.
In today's world you will rarely
come across error number CS0003 as it signifies an out of memory condition.
With RAM so cheap today, we will never ever run out of memory. If we do, then
the compiler will use our hard disk as memory. This is called virtual memory, and
if you come across a CS0003 then consider yourself blessed.
a.cs
class zzz
{
public static void Main()
{
int i;
}
}
Compiler Warning
a.cs(5,5): warning CS0168: The variable 'i' is declared but
never used
A variable when not used in the
program gives us a benign warning. Some software companies hate compilers
producing even a single warning. So, to convert warnings into errors, they
implement the /warnaserror option as in
>csc /warnaserror a.cs
This produces the same warning in
the form of an error.
Compiler Error
a.cs(5,5): error CS0168: The variable 'i' is declared but
never used
As an error is reported, the
compiler does not generate an exe file.
The documentation says that the
message number should be CS0004 in the above case. But we fail to understand it
as our error number is reported as CS0168.
a.cs
class
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
{
}
Compiler Error
a.cs(1,7): error CS0645: Identifier too long
There are limits to everything in
life. In C#, a user defined type cannot exceed 512 characters. These are the
limits that the designers imposed on us lowly programmers. Why on earth would
anyone create a type or class name larger than 32 characters is beyond our
imagination. The above information is useful in game shows to test one's
knowledge of unnecessary trivia!
a.cs
class zzz
{
public static void Main()
{
string s = -"hell";
}
}
Compiler Error
a.cs(5,12): error CS0023: Operator '-' cannot be applied to
operand of type 'string'
Not all operators can be applied
to operands of any data type. So, the unary minus operator cannot be applied to
strings. The designers of the string class decided not to have an overload for
the minus operator for reasons known only to them. Thus, operator overloading
lets you teach an old dog new tricks. You can associate an operator to work
with operands of different data types.
Compiler Error
error CS0025: Standard library file
'C:\WINDOWS\MICROSOFT.NET\FRAMEWORK\V1.0.2204\mscorlib.dll' could not be found
We received the above error when
we renamed mscorlib.dll in the above subdirectory to xxx.dll. The compiler,
csc, expects certain files in certain directories. If those files are not
present we get a CS0025 error. The best alternative here is to reinstall the
.NET framework.
a.cs
class aaa
{
}
public class zzz
{
public void abc(aaa a)
{
}
public static void Main ()
{
zzz a = new zzz();
a.abc(5);
}
}
Compiler Error
a.cs(6,13): error CS0051: Inconsistent accessibility:
parameter type 'aaa' is less accessible than method 'zzz.abc(aaa)'
Thou shall not spend beyond your
means is what has been always taught but we never practiced the adage. Never
keep friends that spend more money than you have. Commonsense? In the above
example, the class zzz is public and we are calling a function abc in it. This
function accepts a parameter that looks like aaa. Unfortunately, as the class
aaa has no access modifiers the default is internal. The class zzz as mentioned
earlier is public, so it is higher in accessibility than internal. They need to
have the same or higher accessibility. The only way out is to remove public
from zzz or add a public to class aaa. Also, the class aaa can be public and
class zzz may be internal and all yet work fine.
So, as we said before, equalize
to higher accessibility not lower.
a.cs
class aaa
{
}
public class zzz
{
public aaa p1
{
get
{
return new aaa();
}
}
}
Compiler Error
a.cs(6,12): error CS0053: Inconsistent accessibility: property
type 'aaa' is less accessible than property 'zzz.p1'
The same rules apply everywhere.
We cannot return an object aaa from a property p1 as it is less accessible than
the class zzz.
a.cs
class aaa
{
}
public class zzz
{
public aaa this[int i]
{
get
{
return new aaa();
}
}
}
Compiler Error
a.cs(6,12): error CS0054: Inconsistent accessibility: indexer
return type 'aaa' is less accessible than indexer 'zzz.this[int]'
Ditto for indexers. They have a
separate error message for each concept even though a common one would suffice.
a.cs
class aaa
{
}
public class zzz
{
public int this[aaa i]
{
get
{
return 0;
}
}
}
Compiler Error
a.cs(6,12): error CS0055: Inconsistent accessibility:
parameter type 'aaa' is less accessible than indexer 'zzz.this[aaa]'
The same rules that hold good for
return values also stand true for parameter types as an indexer can have any
type as a parameter.
To stop further repetition, if an
operator returns an aaa in the above case we would get CS0056 and a CS0057 if
the parameter is inaccessible. CS0058 deals with delegates and CS0059 for
parameters to delegates.
a.cs
class aaa
{
}
public class zzz : aaa
{
}
Compiler Error
a.cs(4,14): error CS0060: Inconsistent accessibility: base
class 'aaa' is less accessible than class 'zzz'
We should never ever enter into a
marriage with someone far better than us. It simply does not work! In the same
way, we cannot derive from a class that is less accessible than we are. In this
case, aaa is internal and we are public. Lest you have forgotten, public has no
rules associated with it whereas internal applies to the current source file
only.
a.cs
interface aaa
{
}
public interface zzz : aaa
{
}
Compiler Error
a.cs(4,18): error CS0061: Inconsistent accessibility: base
interface 'aaa' is less accessible than interface 'zzz'
The same rules apply to an
interface as to a class. We only have a separate error message.
a.cs
using System;
using System;
Compiler Error
a.cs(2,7): warning CS0105: The using directive for 'System'
appeared previously in this namespace
For various reasons we are not
allowed to use the same using directive more than once in our program. There
are many things in life that one just does not understand. It does not cause
anyone any harm if we include the same using twice. Many people don't do things
unless told twice. But, who are we to argue with a compiler?!
a.cs
class zzz : yyy
{
new int i;
}
class yyy
{
}
Compiler Warning
a.cs(3,9): warning CS0109: The member 'zzz.i' does not hide an
inherited member. The new keyword is not required.
The keyword new is used for
versioning. It lets you create a new member altogether and has nothing to do
with the ones having the same name in the base class. In this case, i is not
present in the base class but yet we have used the keyword new with i in zzz.
Here the new keyword is redundant but the compiler gives us only a warning and
not an error. A warning is something that is not at all serious.
a.cs
class zzz : yyy
{
public virtual override void abc()
{
}
}
class yyy
{
public virtual void abc()
{
}
}
Compiler Error
a.cs(3,30): error CS0113: A member 'zzz.abc()' marked as
override cannot be marked as new or virtual
Fire and water do not mix with
each other. In the same way there are certain modifiers which cannot be used in
conjunction with each other. When we override a function, it replaces a
function with the same name in a base class. Also, if we add the new modifier,
then we are saying that it overrides the base class function. A contradiction
of the first order!
A function can only be overridden
if it is marked virtual in the base class. No point in saying it again.
Override means replace the function in the base class. At the same time if we
use the modifier abstract, then we are saying the function has no code. How on
earth can we override a function in the base class with one that has no code at
all? Two wrongs do not make a right!
a.cs
class zzz : yyy {
public override void abc()
{
}
}
class yyy
{
public void abc(int i)
{
}
}
Compiler Error
a.cs(2,22): error CS0115: 'zzz.abc()': no suitable method
found to override
A function is not known by its
name but by its signature. In this case we have two functions carrying the same
name but with different signatures. Thus in class zzz there is no suitable
function abc in class yyy to override and hence the error. We are asking the
compiler to override a function but there is no such function in the base class
to override. In the case of new, we only received a slap on our wrists, a
warning. Here we get an error instead.
a.cs
public class zzz {
static zzz(int o)
{
}
}
Compiler Error
a.cs(2,8): error CS0132: 'zzz.zzz(int)': a static constructor
must be parameterless
Static constructors are a new
concept in programming languages. They are called at the time of loading the
class and hence we can never call them, only the system calls them. The system
never calls them with parameters and hence the above error indicates that a
static constructor cannot accept parameters.
a.cs
class zzz
{
public static int i = 2;
public static void Main()
{
{
int i = 6;
}
i++;
}
}
Compiler Error
a.cs(9,1): error CS0135: 'i' conflicts with the declaration
'zzz.i'
The problem here is a logical one
and not one of syntax. The variable i created in function Main dies at the end
of the brace. Then the static i created outside Main is incremented. What the
compiler is upset about is the fact that in the Main function it encounters two
variables with the same name i. Being uncomfortable with this situation, it
drops an error.
The meaning of a variable must
not be changed within a function, thus name hiding generates the above error.
a.cs
class yyy
{
}
class zzz
{
public static void Main()
{
try {}
catch ( yyy a) {}
}
}
Compiler Error
a.cs(9,9): error CS0155: The type caught or thrown must be
derived from System.Exception
The catch clause takes a
parameter which is either an instance of a class System.Exception or a class
derived from System.Exception. Here yyy is not derived from System.Exception
and hence the error.
a.cs
class zzz {
int i;
public int j;
public static void Main() {
}
}
Compiler Error
a.cs(2,5): warning CS0169: The private field 'zzz.i' is never
used
a.cs(3,12): warning CS0649: Field 'zzz.j' is never assigned
to, and will always have its default value 0
a private member and a public
member when not used gives two different warnings. The second warning very
clearly informs us that the public variable has been initialized to zero, which
does not happen in the case of private variables.
a.cs
class zzz
{
int i;
public int j;
public static void Main()
{
zzz a = new zzz();
System.Console.WriteLine(a.i+" " + a.j);
}
}
Compiler Warning
a.cs(3,5): warning CS0649: Field 'zzz.i' is never assigned to,
and will always have its default value 0
a.cs(4,12): warning CS0649: Field 'zzz.j' is never assigned
to, and will always have its default value 0
Output
0 0
However, if we create an object
that looks like zzz, then the compiler does not distinguish between public and
private and gives the same warning. Contrast it with the situation earlier. You
can figure out these different warnings yourselves.
a.cs
struct yyy
{
public int i;
}
class zzz
{
public static void Main()
{
yyy a;
System.Console.WriteLine(a.i);
}
}
Compiler Error
a.cs(10,26): error CS0170: Use of possibly unassigned field
'i'
The designers of the C# language
investigated as to why programs fail very often. They came about with the
conclusion that programmers hate initializing variables. These variables, thus,
have a random value when they are being used. To eliminate such errors, the
designers forbade us from using a variable without giving it an initial value.
A structure is also a collection of variables and what applies to one variable
also applies to a collection. Thus, the compiler makes sure that each and every
variable is given a value before we can use them.
a.cs
class zzz
{
public static void Main()
{
base = 10;
System.Console.WriteLine(base);
}
}
Compiler Error
a.cs(5,1): error CS0175: Use of keyword base is not valid in
this context
a.cs(6,26): error CS0175: Use of keyword base is not valid in
this context
Like it or not, all objects are
derived from a base class called Object. If we happen to be in a derived class
and we want to access a base class member irrespective of whether it is hidden
or not, the base keyword is to be used. This keyword is to be used to access
base class members only.
a.cs
class zzz
{
public void abc(out int i)
{
}
}
Compiler Error
a.cs(3,13): error CS0177: The out parameter 'i' must be
assigned to before control leaves the current method
An out parameter must be
initialized before the function ends. This is because an out parameter does not
have to be initialized at the time of calling the function. The compiler
guarantees this and ensures that the out variable has been given a value. The
reverse applies to ref also. We have to give ref parameters a value before
calling a function.
a.cs
class zzz
{
public extern void abc()
{
}
}
Compiler Error
a.cs(3,20): error CS0179: 'zzz.abc()' cannot be extern and
declare a body
Whenever we specify a function as
extern, it is our way of telling the compiler that the code of the function is
located in a different file. Hence, we should not be allowed to add code to our
function. If we do break this rule, we will get the above error. Extern
functions cannot have a definition.
a.cs
class zzz
{
public abstract extern void abc();
}
Compiler Error
a.cs(3,29): error CS0180: 'zzz.abc()' cannot be both extern
and abstract
The modifiers extern and abstract
both finally mean the same. No code allowed for the function. In the case of
abstract, the code will be supplied by the derived class and in extern from
some other place, maybe outside the current file. Thus abstract and extern are
mutually exclusive.
a.cs
public class zzz
{
static string s;
[System.Diagnostics.ConditionalAttribute(s)]
static void Main()
{
}
}
Compiler Error
a.cs(4,42): error CS0182: An attribute argument must be a
constant expression, typeof expression or array creation expression
The parameters passed to an
attribute can be one of the types as mentioned in the above error. Thus we
cannot use a variable as a parameter in the above case even though we are
giving it a string data type, which the parameter to the attribute expects it
to be.
a.cs
class zzz
{
public static void Main()
{
if (((System.Object) null) is string)
;
}
}
Compiler Error
a.cs(5,7): error CS0186: Use of null is not valid in this
context
A null represents no object at
all. Thus we are not allowed to cast null into any other data type.
a.cs
struct yyy
{
int j;
yyy(int i)
{
abc();
j = i;
}
void abc()
{
}
}
Compiler Error
a.cs(6,1): error CS0188: The this object cannot be used before
all of its fields are assigned to
In a structure, we must first
initialize all the members of the structure before calling a function within
it. Remember all references are prefaced by a this. Calling the function abc in
yyy is equivalent to this.abc().
a.cs
struct yyy
{
yyy(int i)
{
abc();
}
void abc()
{
}
}
Compiler Error
a.cs(5,1): error CS0188: The this object cannot be used before
all of its fields are assigned to
So pigheaded is the compiler that
even though we have no variables in the structure it yet gives us an error. The
compiler does not realize that we have no variables at all in the structure.
Maybe the next version of the compiler will not give us such an error.
The only explanation we can
provide is that if we have a constructor with parameters, then we have to
initialize at least one variable. This also means we need at least one variable
in the structure.
a.cs
class zzz
{
public readonly int i = 10;
zzz()
{
i = 3;
}
public static void Main()
{
zzz a = new zzz();
a.i = 4;
}
}
Compiler Error
a.cs(11,1): error CS0191: A readonly field cannot be assigned
to (except in a constructor or a variable initializer)
A readonly variable can only be
initialized in a constructor or at the time of creation. Anywhere else is a
no-no as it would defeat the very concept of being readonly.
a.cs
class zzz
{
public static readonly int i = 10;
zzz()
{
i = 3;
}
public static void Main()
{
}
}
The error reported is the same as
before as the readonly variable i is static and the constructor in which it is
being initialized is not static. Add the static modifier to the constructor and
watch the error fly away.
a.cs
class zzz
{
public static readonly int i = 10;
public static void abc( ref int j)
{
}
public static void Main()
{
zzz.abc(ref i);
}
}
Compiler Error
a.cs(9,13): error CS0199: A static readonly field cannot be
passed ref or out (except in a static constructor)
A static readonly field cannot be
passed as a parameter to a function like a normal readonly variable.
A statement comprises five
entities: an assignment, increment, decrement, call and a new.
a.cs
public class zzz
{
public void GetEnumerator ()
{
}
public static void Main ()
{
zzz z = new zzz();
foreach (zzz x in z)
{
}
}
}
Compiler Error
a.cs(9,1): error CS0202: The call to GetEnumerator must return
a class or a struct, not 'void'
The GetEnumerator function must
return a class or a struct, surely not a void.
One error that we did not have
the heart to shown you is CS0204. This one pops up when you have more than
65535 local variables in your program. Who on earth has the time to create so
many variables and we doubt whether anyone on earth has ever seen this error
message? Trust is what makes the world go round and we trust the documentation.
a.cs
public class zzz
{
public static void abc(params int[] a, __arglist)
{
}
}
Compiler Error
a.cs(3,24): error CS0231: A params or __arglist parameter must
be the last parameter in a formal parameter list
We cannot use the __arglist and
params together as parameters to a function. Either one of it is used. This is
because both of them are an array and they mop up whatever is left over of the
parameters. The __arglist is used to access parameters passed to a function.
a.cs
public class zzz
{
public static void Main()
{
int i;
System.Console.WriteLine(sizeof(i));
}
}
Compiler Error
a.cs(6,26): error CS0233: sizeof can only be used in an unsafe
context (consider using System.Runtime.InteropServices.Marshal.SizeOf)
The sizeof is a remnant of the C
programming language. Hence we can only use it in an unsafe context. In our
opinion, these are unnecessary restrictions placed on us by the compiler. Who
listens to the underdog?
a.cs
public class zzz
{
public static void Main()
{
int i = 10;
System.Console.WriteLine(System.Runtime.InteropServices.Marshal.SizeOf(i));
}
}
Output
4
We took the advise of the error
message and used the SizeOf function in the class Marshal. We did receive the same answer that sizeof
would have given us in unsafe conditions.
The only hitch here is that i
must be initialized in advance. Such is not the case with the sizeof keyword.
This is one of the major difference between a function and a keyword. Something
that the language understands is treated differently from a parameter to a
function.
a.cs
abstract class zzz
{
public abstract void abc()
{
}
}
Compiler Error
a.cs(3,22): error CS0500: 'zzz.abc()' cannot declare a body
because it is marked abstract
The concept of abstract expects
the derived class to write the code for the abstract functions. Thus, we cannot
write the code ourselves by specifying a body.
a.cs
abstract class zzz
{
public virtual abstract void abc();
}
Compiler Error
a.cs(3,30): error CS0503: The abstract method 'zzz.abc()'
cannot be marked virtual
The compiler hates repetition. An
abstract function is by default virtual and it gets upset if you specify
virtual again. Maybe the next version should be a lot more considerate when we
state the obvious again. Honestly, this would slim down the number of error
messages.
a.cs
class zzz : yyy {
public override void abc()
{
}
}
class yyy
{
public int abc;
}
Compiler Error
a.cs(2,22): error CS0505: 'zzz.abc()' : cannot override;
'yyy.abc' is not a function
We can only override a function
provided a function with the same name is present in the base class. Here abc
is an int in the base class, not a function name and hence the error.
a.cs
class zzz : yyy
{
static zzz() : base()
{
}
}
class yyy
{
}
Compiler Error
a.cs(3,8): error CS0514: 'zzz.zzz()': static constructor
cannot have an explicit this or base constructor call
A static constructor is not
allowed to call the static constructor of the base class using the keyword
base. The problem with static is that anything to do with it has to be known at
compile time only whereas the keyword this has a value only at run time. Plus,
static functions are not passed this and base as parameters.
a.cs
class zzz
{
public static zzz()
{
}
}
Compiler Error
a.cs(3,15): error CS0515: 'zzz.zzz()': access modifiers are
not allowed on static constructors
A static constructor is called
when the object is loaded. Thus, as it is an internal thing, we are not allowed
to use any access modifiers on static constructors.
a.cs
class zzz
{
public zzz() : this()
{
}
}
Compiler Error
a.cs(3,8): error CS0516: Constructor 'zzz.zzz()' cannot call
itself
A constructor can use the keyword
this and base to call any other constructor but itself.
a.cs
class zzz {
public zzz() : this(10)
{
System.Console.WriteLine("Void");
}
public zzz(int i) : this()
{
System.Console.WriteLine("One");
}
public static void Main()
{
System.Console.WriteLine("Start");
zzz a = new zzz();
}
}
Output
Start
In our belief, the compiler does
not try hard enough to detect circular references. Here the constructors are
blindly calling each other and the compiler is blind to their doings. Thus, it
is easy to go into an indefinite loop while writing code. At times, we may
receive a runtime error stating: Unhandled Exception: StackOverflowException.
a.cs
struct zzz
{
public zzz(int i) : base(i)
{
}
}
Compiler Error
a.cs(3,8): error CS0522: 'zzz.zzz(int)': structs cannot call
base class constructors
Structures cannot call the base
class constructors as they in their very nature are sealed. Hence, what the
structure derives from cannot be called also. The other reason could be that
they are created on the stack. Thus, structures and classes in a sense are a
lot similar but a lot dissimilar too.
a.cs
struct zzz
{
yyy a;
}
struct yyy
{
zzz b;
}
Compiler Error
a.cs(7,5): error CS0523: Struct member 'yyy.b' of type 'zzz'
causes a cycle in the structure layout
You rely on someone to do a job
and he relies on you to do the same job. Chaos is the result. Hence, in the
struct zzz we have a member a that is an instance of a type yyy and struct yyy
in turn has a member called b that is an instance of zzz. This causes a cycle.
The complier thus throws its hands up in the air and gives up. Cyclic
references are like plague
a.cs
interface iii
{
public class zzz
{
}
}
Compiler Error
a.cs(3,14): error CS0524: 'zzz': interfaces cannot declare
types
You can do lots of things in an
interface but you cannot create your own class within them. A nested class is not permissible in an
interface. The reason for the restriction is that classes carry code with them
and an interface cannot have any code in it.
a.cs
interface iii
{
int i;
}
Compiler Error
a.cs(3,1): error CS0525: Interfaces cannot contain fields
Interfaces are all fluff. They
cannot have anything concrete. They are only rules that others have to obey.
Thus, a field, which is something finished, something complete cannot reside in
an interface.
a.cs
interface iii {
iii();
}
Compiler Error
a.cs(2,1): error CS0526: Interfaces cannot contain
constructors
Interfaces cannot have a whiff of
code. So having constructors is out of question. It cannot also have the
definition or a prototype of a constructor as it will then have to be filled
with code. Thus, constructors are not allowed to have a constructor definition.
a.cs
interface iii
{
}
class zzz : iii,iii
{
}
Compiler Error
a.cs(4,17): error CS0528: 'iii' is already listed in interface
list
The compiler would hate seeing a
movie with a double role. You cannot derive from a interface twice. A class can
derive from multiple interface but not from the same one twice. Makes sense.
Why would anyone do something so foolhardy?
a.cs
interface iii : jjj {
}
interface jjj : iii
{
}
Compiler Error
a.cs(1,11): error CS0529: Inherited interface 'jjj' causes a
cycle in the interface hierarchy of 'iii'
Anything cyclic is a problem for
the compiler. Here we will go on and on in a indefinite loop as interface iii
depends upon interface jjj which again depends upon iii.
a.cs
abstract public class zzz
{
abstract public void abc();
}
abstract public class yyy : zzz
{
new abstract public void abc();
}
Compiler Error
a.cs(7,26): error CS0533: 'yyy.abc()' hides inherited abstract
member 'zzz.abc()'
Class yyy is derived from zzz and
they both have an abstract function called abc. In the class yyy abc has a new
modifier, thus it has nothing to do with the base class abc. The problem is
that the base class abc has no code at all and thus making the yyy class abc
new makes no sense. New assumes that we are creating a different function over
the base class.
a.cs
public class zzz : yyy
{
public static void abc()
{
}
}
interface yyy
{
void abc();
}
Compiler Error
a.cs(1,14): error CS0536: 'zzz' does not implement interface
member 'yyy.abc()'. 'zzz.abc()' is either static, not public, or has the wrong
return type.
Any mistake on our part gives an
error. Interface yyy contains a function abc which is to be implemented in zzz.
But while implementing it in zzz, we
made it static. The compiler is very clear on one point. Implement the entire
function including return type and access modifiers as they are in the
interface otherwise conk out. No deviations from the original is allowed under
any circumstances.
a.cs
class zzz : yyy
{
void yyy.abc()
{
}
}
class yyy
{
}
Compiler Error
a.cs(3,6): error CS0538: 'yyy' in explicit interface
declaration is not an interface
We are allowed to specify the
interface name before a function with a dot as a separator. This is because we
are allowed to implement a class from multiple interfaces, which may carry the
same function name. However, yyy is the name of a class and not a interface.
a.cs
interface zzz : yyy
{
void yyy.abc();
}
interface yyy
{
void abc();
}
Compiler Error
a.cs(3,6): error CS0541: 'yyy.abc': explicit interface
declaration can only be declared in a class or struct
We are only allowed to use the
explicit interface notation in a class or a structure. Within another
interface, it is not accepted. This speaks of sound common sense as an
interface can never ever carry code and thus cannot carry the definition or
code of the function either. Thus specifying the interface the function dwelled
in does not make any sense.
a.cs
class zzz : yyy
{
public override int i
{
set {}
}
}
class yyy
{
public int i;
}
Compiler Error
a.cs(3,21): error CS0544: 'zzz.i' : cannot override; 'yyy.i'
is not a property
We can have a property called i
in the derived class and a variable called i in the base class. The compiler
can live with it and they can both coexist. The problem starts the moment we
override the property i in the derived class. This is not allowed as we have no
property by the same name in the base class. We have only a lowly variable.
a.cs
class zzz : yyy
{
public override int i
{
set {}
get { return 0;}
}
}
class yyy {
virtual public int i
{
set { }
}
}
Compiler Error
a.cs(6,1): error CS0545: 'zzz.i.get': cannot override because
'yyy.i' does not have an overridable get accessor
A property does not exist by
itself. It comes along with a get and set accessor. You cannot exceed what the
designers chose to implement in the base class. Only things that are virtual in
the base class can be overridden. So, the only way out of the above quandary is
to define a get like the set.
a.cs
sealed class zzz
{
public virtual void abc()
{
}
}
Compiler Error
a.cs(3,21): error CS0549: 'zzz.abc()' is a new virtual member
in a sealed class 'zzz'
The sole purpose of virtual in
life is to ensure overriding of a function in he base class within the derived
class. A sealed class cannot be used as a base class and hence virtual
functions are a contradiction in terms.
a.cs
class zzz : iii
{
int iii.i
{
set {}
}
}
interface iii
{
int i
{
get;
}
}
Compiler Error
a.cs(3,5): error CS0551: Explicit
interface implementation 'zzz.iii.i' is missing accessor 'iii.i.get'
a.cs(5,1): error CS0550: 'zzz.iii.i.set' adds an accessor not
found in interface member 'iii.i'
a.cs(1,7): error CS0535: 'zzz' does not implement interface
member 'iii.i.get'
In an interface we have a
property i with a get and no set. In the derived class, we have not added the
same property but instead given a set property. The compiler throws error
messages as it feels we are confused with what we were trying to achieve.
a.cs
public class zzz
{
public ~yyy()
{
}
}
Compiler Error
a.cs(3,9): error CS0574: Name of destructor must match name of
class
A destructor is called a
destructor because it is of the same name as the name of the class. You cannot
have any other name starting with a ~ in a class.
a.cs
interface iii
{
void abc();
}
public class zzz : iii
{
[System.Diagnostics.ConditionalAttribute("hi")]
void iii.abc()
{
}
}
Compiler Error
a.cs(7,2): error CS0577: Conditional not valid on
'zzz.iii.abc()' because it is a constructor, destructor, operator, or explicit
interface implementation
An attribute cannot be used
anywhere and everywhere. Fools rush in where angels fear to tread. Thus, we
cannot use the ConditionalAttribute on a constructor, destructor, operator, or
explicit interface implementation. The error message informs us the same.
a.cs
public class zzz
{
[System.Diagnostics.ConditionalAttribute("hi")]
int abc() {
}
}
Compiler Error
a.cs(3,2): error CS0578: Conditional not valid on 'zzz.abc()'
because its return type is not void
When creating an attribute you
can be extremely picky about where it can be used. The ConditionalAttribute can
be used only above functions that return void. One more rule to remember!
a.cs
using System.Runtime.CompilerServices;
public class zzz
{
[IndexerName("abc", "def")]
public int this [int index]
{
set {}
}
}
Compiler Error
a.cs(3,14): error CS0580: Too many unnamed arguments to
attribute 'IndexerName'
Attributes have their own set of
rules and regulations. The designers of the IndexerName attribute allowed only
a single parameter of a string data type. We are passing it two strings and
hence the error.
a.cs
using System.Runtime.CompilerServices;
public class zzz
{
[IndexerName("abc", vijay=2)]
public int this [int index]
{
set {}
}
}
Compiler Error
a.cs(3,2): error CS0581: Named arguments not allowed on
attribute 'IndexerName'
We are also not allowed to use
named arguments, as the attribute does not understand them.
a.cs
interface iii
{
[System.Diagnostics.ConditionalAttribute("DEBUG")]
void zz();
}
Compiler Error
a.cs(3,2): error CS0582: Conditional not valid on interface
members
We are not allowed to use the
ConditionalAttribute on an interface member. We can decide with the precision
of a stealth bomber where an attribute is allowed. This is one more restriction
on an interface member.
a.cs
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential | LayoutKind.Explicit)]
class zzz
{
}
An attribute cannot have options,
which are contradictory in the definition of the attribute. In the above case,
both of them are valid.
a.cs
class zzz
{
void this [int i]
{
set {}
}
}
Compiler Error
a.cs(3,6): error CS0620: Indexers cannot have void type
Indexers, Properties, Operators
cannot have void return types as they are diligent in the job they perform and
always return values.
a.cs
class zzz
{
virtual void abc()
{
}
}
Compiler Error
a.cs(3,14): error CS0621: 'zzz.abc()' : virtual or abstract
members cannot be private
By default, a member in a class
is marked private. This prohibits the derived classes from accessing its
private functions.
A virtual function allows derived
classes to override its function whereas an abstract function is implemented in
a derived class. Hey, wait a minute! A private function cannot be accessed in a
derived class as we mentioned a couple of lines earlier. Thus, a private
function cannot be tagged with the modifiers virtual and abstract.
a.cs
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Explicit)]
struct zzz
{
[FieldOffset(5)]
public int i;
public int j;
}
Compiler Error
a.cs(7,12): error CS0625: 'zzz.j' : Instance field types
marked with StructLayout(LayoutKind.Explicit) must have a FieldOffset
attribute.
The StructLayout attribute lets
you decide on the memory layout for the structure. Normally the compiler
decides where in memory the individual fields will start but at certain times,
we would like to decide where in memory the fields should begin.
The parameter to the attribute,
which will give us complete freedom in laying out the fields in memory is
called LayoutKind.Explicit. This freedom comes at a price. We have to
individually specify where each field starts using the FieldOffset Attribute.
This is no partnership where we supply some and the compiler does the rest. The
destiny of the structure is now in our hands. We cannot miss out any field as
we did in the above example with variable j.
a.cs
sealed class zzz
{
protected void abc()
{
}
public static void Main()
{
}
}
Compiler Error
a.cs(3,16): warning CS0628: 'zzz.abc()' : new protected member
declared in sealed class
Remember warnings are not
life-threatening at all. A protected member only allows a derived class to use
a function and a sealed class cannot be derived from, hence the compiler thinks
we are confused or lost. May be it thinks we should have used private instead
as in this case the protected gets downgraded to private access. No big deal
and thus a warning.
a.cs
class zzz : iii
{
[System.Diagnostics.Conditional("debug")]
public void abc()
{
}
}
interface iii
{
void abc();
}
Compiler Error
a.cs(4,13): error CS0629: Conditional member 'zzz.abc()'
cannot implement interface member 'iii.abc()'
This particular attribute cannot
be used on an interface function. Ask the guys who designed the attribute what
was on his mind when he placed the above restriction.
a.cs
class zzz
{
public int this[ref int i]
{
}
}
Compiler Error
a.cs(3,12): error CS0631: Indexers can't have ref or out
parameters
It does not make any sense for an
indexer to have parameters that can be ref or out and as the parameter to an
indexer is nothing but an index of an array. Normally the parameter to an
indexer would be a number only which cannot be changed. Also, if we used a
variable, changing its value in an indexer would lead to confusion all around.
a.cs
[zzz]
class zzz {
}
Compiler Error
a.cs(1,2): error CS0616: 'zzz': is not an attribute class
An attribute must be a class
derived from System.Attribute. This condition must be adhered to at all costs.
This is because the system can call lots of functions from the System.Atribute
class and we can override the functions if we want to change the behavior of
the attribute.
a.cs
[xxx]
public class zzz {
[yyy]
int i;
}
abstract class yyy : System.Attribute
{
}
class xxx : yyy
{
}
Compiler Error
a.cs(4,2): error CS0653: Cannot apply attribute class 'yyy'
because it is abstract
An abstract class cannot get a
job anywhere as it cannot be used anywhere. Such a class is incomplete and
unless completed it cannot be of any help to society. Thus, the class yyy, an
abstract class, cannot participate as an attribute but class xxx can as it is
not abstract. xxx must implements all the abstract functions of class yyy.
a.cs
public class zzz
{
public static void Main()
{
int i = abc;
}
public static int abc()
{
return 1;
}
}
Compiler Error
a.cs(5,9): error CS0654: Method 'zzz.abc()' referenced without
parentheses
Function names have no great
significance in the C# programming language. We only use them to execute a
function after specifying the name and () brackets with parameters within them.
a.cs
public class zzz {
public static public void Main()
{
}
}
Compiler Error
a.cs(3,15): error CS1004: Duplicate 'public' modifier
Two of the same is what the
compiler hates. Here we are not allowed to specify the same modifier twice. Hey
we meant no harm but who is listening. They do not have to be physically
together on the line for the error to be flagged.
a.cs
public class zzz {
public static void Main()
{
object *p;
}
}
Compiler Error
a.cs(5,8): error CS1005: Indirection to managed type is not
valid
A * signifies a pointer and the
managed types like object etc cannot be accessed through a pointer. Pointers
were created for being used by the value types.
a.cs
public class zzz
{
public int i
{
set {}
set {}
}
}
Compiler Error
a.cs(6,5): error CS1007: Property accessor already defined
You cannot say or do the same
thing twice. As we are creating the same set accessor twice, which one should
the compiler take heed off. It chooses neither and gives you a simple error.
a.cs
public class zzz {
int i
{
aa {}
}
}
Compiler Error
a.cs(4,1): error CS1014: A get or set accessor expected
A property can only contain a get
and a set.. We cannot place any arbitrary function name within a property.
a.cs
public class zzz
{
public zzz () :
{
}
}
Compiler Error
a.cs(4,1): error CS1018: Keyword this or base expected
After the name of the
constructor, we have complete control over which constructors to call though it
is optional. If we specify a :, then we have to use base or this to call the
appropriate constructor. If we leave it blank, all hell breaks loose and we get
an error.
a.cs
class zzz
{
}
}
Compiler Error
a.cs(4,1): error CS1022: Type or namespace definition, or
end-of-file expected
An extra brace } added by mistake
does not result in a simple English like error. Instead, we get end of file
expected. Where is the neighbourhood going these days?
a.cs
#vijay
Compiler Error
a.cs(1,2): error CS1024: Preprocessor directive expected
Anything after the # or pound
sign can only be the name of a preprocessor symbol and not anything else. As
there are very few preprocessor symbols, we do not have much of a choice here.
a.cs
#if true /*
*/
#endif
Compiler Error
a.cs(1,10): error CS1025: Single-line comment or end-of-line
expected
After a preprocessor directive,
we can only use the single line comments and not the multiple line comments.
a.cs
#if true 2
#endif
Compiler Error
a.cs(1,10): error CS1025: Single-line comment or end-of-line
expected
Any other preprocessor error also
results in a CS1025. May be as the preprocessor has lost its importance in C#
compared to C, they did not have separate error messages for the preprocessor
and used CS1025 as a catch all for all errors.
a.cs
#if ( a== b
#endif
Compiler Error
a.cs(1,13): error CS1026: ) expected
However, some common errors like
closing a ) bracket are caught by the compiler.
a.cs
#endif
Compiler Error
a.cs(2,2): error CS1028: Unexpected preprocessor directive
When you catch the compiler with
its pants down it gives you error CS1028. Here the compiler saw an #endif with
no matching #if. Instead of sending us to the loony bin, it gave us the above
error. Hey, relax, mistakes always happen!
a.cs
/*
Compiler Error
a.cs(1,1): error CS1035: End-of-file found, '*/' expected
All good things in life must come
to an end even though we do not want them to. In this case, we have a start of
a multi-line comment but no end of multi line comment in sight.
a.cs
public class zzz
{
public static void Main()
{
string b = @"hell;
}
}
Compiler Error
a.cs(5,12): error CS1039: Unterminated string literal
All strings have to end with
" as they start off with a ". If the @ sign is not around, you will
receive another error. Like in life end what you start.
a.cs
/* */ #define aa
Compiler Error
a.cs(1,7): error CS1040: Preprocessor directives must appear
as first non-whitespace character on a line
We all like coming first in life
and it is the same with a preprocessor directive. We cannot place it anywhere
else, it has to be the first character
of a line. The number of spaces or white spaces are counted as valid characters
and like life ignores you and me, spaces are ignored by the compiler.
a.cs
public class zzz
{
public st\u0061tic void Main()
{
}
}
Compiler Error
a.cs(3,20): error CS1519: Invalid token 'void' in class,
struct, or interface
A Unicode character set begins
with a \u and a number, which the Unicode character is known by. A small a is
known by the number 97 or 61 in hex. We are not allowed to use the Unicode
characters in keywords. Maybe it brings in more work for the compiler.
a.cs
public class zzz
{
public static void Main()
{
abc(ref 10);
}
public static void abc(ref int i)
{
}
}
Compiler Error
a.cs(5,9): error CS1510: A ref or out argument must be an
lvalue
A ref or an out must be a lvalue.
An lvalue is nothing but a variable that represents some memory. A property is
not an lvalue as it is a function and does not stand for a memory location. A
ref and out parameter require a memory location.
a.cs
class zzz : yyy
{
public static void Main ()
{
base.j = 3;
}
}
class yyy
{
public static int j;
}
Compiler Error
a.cs(5,1): error CS1511: Keyword base is not available in a
static method
Static is like the odd kid on the
block. It cannot perform a lot more than a non-static member. It has, for
example, no access to the keyword base with which it can access members of the
base class. The reason being that static means one and only one and this and
base are used to access multiple instance values.
a.cs
class zzz : yyy
{
int k = base.j;
}
class yyy
{
public static int j=10;
}
Compiler Error
a.cs(3,9): error CS1512: Keyword base is not available in the
current context
We are not allowed to use the
keyword base outside of a function, property or a constructor. You can consider
it as an extra parameter to a function. It represents the class we are derived
from.
a.cs
class zzz
Compiler Error
a.cs(3,4): error CS1514: { expected
Whenever we use keywords like
class, namespace, the compiler checks for an open the brace. If this character is omitted, then it stops
in its tracks and immediately before you can say 'halleluiah' it will throw up an
error!
a.cs
class zzz
{
abc()
{
}
}
Compiler Error
a.cs(3,1): error CS1520: Class, struct, or interface method
must have a return type
A method can be placed in any of
the following three places, a class, struct or an interface. There are no
assumptions made by the compiler. All functions have to return a value and even
if they do not, we have to explicitly specify that they do not. In the above
case, the function abc does not return any value and the compiler does not
guess or assume a return value for it.
a.cs
class zzz : yyy[]
{
}
class yyy
{
}
Compiler Error
a.cs(1,18): error CS1521: Invalid base type
Whenever we use an invalid
character in the name of the base class, we are confronted with the above
error. If we use the wrong name of a class, we are given a CS0234 error. Thus,
only an ill-formed base class name causes the above error.
a.cs
class zzz
{
public static void Main()
{
void i;
}
}
Compiler Error
a.cs(5,1): error CS1547: Keyword 'void' cannot be used in this
context
A void data type can only be used
with a function. It denotes absence of a return value. A variable cannot
represent absence or no value. Thus, no data type can represent a void or no
value. For these reasons, the compiler has reserved one error message
explicitly for it.
a.cs
class zzz
{
public static void Main()
{
5 + [ + throw + void;
}
}
Compiler Error
a.cs(5,5): error CS1525: Invalid expression term '['
a.cs(5,9): error CS1525: Invalid expression term 'throw'
a.cs(5,17): error CS1525: Invalid expression term 'void'
You are not allowed to write
whatever you want and wherever you want especially in an expression. We are not
allowed to use reserved words indiscriminately anywhere we like. Thus, words
like void are a no-no in expressions. The compiler reserves error number CS1457
for your sloppiness.
a.cs
class zzz
{
public static void Main()
{
zzz a = new zzz;
}
}
Compiler Error
a.cs(5,16): error CS1526: A new expression requires () or []
after type
The compiler is extremely
unforgiving. If we forget even the () after new, it screams its head off at us.
Whenever we call new, we are executing a constructor, which may or may not be
passed parameters. That is the rationale behind the () brackets after new. Even
though we have no parameters to be passed to the constructor, we have to use
the new syntax. Ditto for [].
a.cs
class zzz {
public static void Main()
{
zzz a(3);
}
}
Compiler Error
a.cs(5,6): error CS1528: Expected ; or = (cannot specify
constructor arguments in declaration)
In languages like C++, to create
an object that looks like zzz, either new was used or the class itself as in
zzz a(3). This would create an object like zzz and call the constructor with
one int parameter. The parameter would be given he value of three.
C# treats value types and objects
in the same manner. As most of us come from the C++ school of writing code, to
prevent any such errors, the above error check has been introduced. If you have
a historical perspective of life, everything gets much clearly. One bone we
pick with the world is that nobody teaches history anymore. Those who do not
learn from history are forced to relive its mistakes, right?
a.cs
#line "abc"
Compiler Error
a.cs(1,7): error CS1576: The line number specified for #line
directive is missing or invalid
The #line directive requires by
divine law two parameters, the new line number and the file name. Stating only
one is not a valid option.
a.cs
#line 10 abc
Compiler Error
a.cs(1,10): error CS1578: Filename, single-line comment or
end-of-line expected
The #line is an extremely
sensitive animal. It needs a number followed by double quotations marks and
maybe a single line comment. Anything else will result in an error. Seen anyone
more stubborn in life?
a.cs
class zzz {
sealed override public void abc() {
}
}
Compiler Error
a.cs(2,29): error CS0115: 'zzz.abc()': no suitable method
found to override
The documentation clearly states that sealed can be used with a
function within a class. A sealed function as per the documentation can only be
used with an override method. Remove the override modifier and the error
displayed is as follows:
a.cs(2,20): error CS0238:
'zzz.abc()' cannot be sealed because it is not an override
The concept of sealed for a
function would prevent change to a single function only and not to an entire
class.
Compiler
Options
When we run the C# compiler as
>Csc a.cs
Microsoft (R) Visual C# Compiler Version 7.00.9030 [CLR
version 1.00.2204.21]
Copyright (C) Microsoft Corp 2000. All rights reserved.
We will first see the Microsoft
logo displayed. Seeing it all the time hurts the eye. Thus Microsoft gives you
a compiler option /nologo that will suppress the logo which would otherwise get
displayed.
>Csc a.cs /nologo
We always run the compiler with
the /nologo option. Nothing great here!
>Csc a.cs /nostdlib
Compiler Error
error CS0518: The predefined type 'System.Byte' is not defined
or imported
The entire System namespace has
to be stored someplace and as of today it is stored in the dll mscorlib.dll.
This dll is searched and loaded always by the compiler thus the net effect is
that the System namespace is always available to us.
With the option of /nostdlib, the
compiler is told to bypass this dll, mscorlib.dll, As the System namespace is
now unavailable to the compiler, an error is reported. For reasons left unknown
to us, the compiler first requires System.Byte from the System namespace.
a.cs
class zzz
{
public static void Main()
{
}
}
namespace System
{
struct Byte
{
}
}
Compiler Error
error CS0518: The predefined type 'System.Int16' is not
defined or imported
Now that we have created a dummy,
System.Byte structure the compiler goes away happy but comes back with another
request. It needs the System.Int16 structure. Can't it demand everything in one
go?
a.cs
class zzz
{
//public static void Main()
//{
//}
}
namespace System
{
struct Byte
{
}
struct Int16
{
}
struct Int32
{
}
}
On entering int16, the compiler
asks for Int32. All this leads to one
conclusion, if you don't load the System namespace, then you have to write code
for all the entities yourself. We tried adding many more structures but
eventually gave up as the list was endless. Rather have the System namespace
loaded from the dll, than key in all the structures ourselves.
a.cs
class zzz
{
public int this[]
{
}
}
Compiler Error
a.cs(3,17): error CS1551: Indexers must have at least one
parameter
An indexer is to be used as an
array and hence must have, at the bare minimum, one parameter to do its job.
Else, we get an error.
a.cs
public class zzz
{
public static void Main()
{
int i;
}
}
Compiler Error
a.cs(5,5): warning CS0168: The variable 'i' is declared but
never used
The compiler produces a large
number of warnings. Some feel that they are too old for anyone to preach them.
For them, the compiler can be commanded to stop generating warning messages.
This option is called /nowarn.
>csc a.cs /nowarn
Gives us the following error
message:
Compiler Error
fatal error CS2006: Command-line syntax error: Missing ':<text>' for '/nowarn' switch
/nowarn is not enough, we need to
specify the error number that is to be suppressed. On giving the option as
/nowarn:168, the compiler will not display warning message 168, the one it
displayed earlier. Multiple warning message numbers are to be separated by a
comma but there is no option available to suppress all of them.
a.cs
public class zzz
{
public static void Main()
{
int i;
yyy a = new yyy();
}
}
b.cs
public class yyy
{
}
>csc *.cs
We are allowed to use wildcards
with the compiler. The above command inturn gets rewritten as csc a.cs b.cs.
>csc /recurse:zzz\*.cs
The /recurse option lets you compile all .cs files in zzz and
its child directories recursively.
>csc /reference:m.dll;m1.dll a.cs
The /reference option lets you
look into .dll files for the code of classes. If you have more than one dll
file to look into, then we need to separate them with a semicolon.
a.cs
public class zzz {
public static void Main()
{
int i;
}
}
Compiler Error
a.cs(5,5): error CS0168: The variable 'i' is declared but
never used
Run the command as
>csc a.cs /warnaserror
The /warnaserror does a very
simple thing. It converts all warnings into errors. This is advisable as a
policy because the compiler gives you a warning for a definite purpose. If a
program compiles without any warnings, chances are good that it will not blow
up in your face ever.
>Csc a1.cs
Compiler Error
error CS2001: Source file 'a1.cs' could not be found
fatal error CS2008: No inputs specified
We get two errors instead of one.
The first error occurs because there is no file called a1.cs in the current
directory. The second error arises as the only source file we gave the compiler
was non-existent and hence the compiler was left with no input source files.
>Csc a.cs a.cs
Compiler Warning
warning CS2002: Source file 'a.cs' specified multiple times
If we give the same source file
name a.cs multiple times, we only get a warning. The compiler ignores this
repetition. You can give the same name
as many times as you like and all of them will be ignored
Create a file z.rep as follows
z.rep
/nologo a.cs b.cs
Run the compiler as
>csc @z.rep
Anything after an @ sign in the
command line is called a response file. This file contains compiler options and
source file names. This just relieves you from writing the options and
filenames on the command line.
Run the command as
>csc @z.rep @z.rep
Compiler Error
error CS2003: Response file 'C:\csharp\z.rep' included
multiple times
Even response files cannot be
mentioned multiple times.
>csc a.cs /r:
Compiler Error
error CS2005: Missing file specification for '/r:'
command-line option
With the /r option, the dll name
is to be specified. In case you forget the dll name, you pay for it with an
error.
>csc a.cs /k:
Compiler Error
fatal error CS2007: Unrecognized command-line option: '/k:'
The compiler does not understand
any option that begins with k:. Thus, the error is reported. Looks like the
command line options are not too many at all.
>csc a.cs @a1.rep
Compiler Error
fatal error CS2011: Unable to open response file
'C:\csharp\a1.rep'
We asked the compiler to open a
response file that does not exist in the csharpbook sub-directory. Hence,
CS2011 error number is reported
a.cs
public class zzz
{
public static void Main()
{
}
}
b.cs
class yyy
{
hell
}
>csc /bugreport:a.txt a.cs b.cs
Microsoft (R) Visual C# Compiler Version 7.00.9030 [CLR
version 1.00.2204.21]
Copyright (C) Microsoft Corp 2000. All rights reserved.
Compiler Error
b.cs(4,1): error CS1519: Invalid token '}' in class, struct,
or interface member declaration
A file is being created with information needed to reproduce
your compiler problem, including the contents of all source code files.
Please describe the compiler problem (press Enter twice to
finish):
Describe what you think should have happened (press Enter
twice to finish):
To create a bugreport, the
compiler asks you to describe the problem that you have faced and then press
enter twice. At this point, we entered
vijay.
The next question that pops up is
for the solution to the problem. Here we key in sonal.
The contents of a.txt are
displayed as follows.
a.txt
### C# Compiler Defect Report, created 08/29/01 19:33:19
### Compiler version: 7.00.9254
### .NET common language runtime version: v1.0.2914
### Operating System: Windows NT 5.0.2195
### User Name: Administrator
### Compiler command line
csc /r:Accessibility.dll /r:Microsoft.Vsa.dll
/r:System.Configuration.Install.dll /r:System.Data.dll /r:System.Design.dll
/r:System.DirectoryServices.dll /r:System.dll /r:System.Drawing.Design.dll
/r:System.Drawing.dll /r:System.EnterpriseServices.dll /r:System.Management.dll
/r:System.Messaging.dll /r:System.Runtime.Remoting.dll
/r:System.Runtime.Serialization.Formatters.Soap.dll /r:System.Security.dll
/r:System.ServiceProcess.dll /r:System.Web.dll /r:System.Web.RegularExpressions.dll
/r:System.Web.Services.dll /r:System.Windows.Forms.Dll /r:System.XML.dll
/bugreport:a.txt a.cs b.cs
### Source file: 'C:\csharpbook\a.cs'
public class zzz
{
public static void Main()
{
}
}
### Source file: 'C:\csharpbook\b.cs'
class yyy
{
hell
}
### Compiler output
b.cs(4,1): error CS1519: Invalid token '}' in class, struct,
or interface member declaration
### User description
vijay
### User suggested correct behavior
sonal
Enter the following commands to
understand the next error message.
>attrib +r a.txt
>csc /bugreport:a.txt a.cs b.cs
Compiler Error
error CS2012: Can't open 'a.txt' for writing
The attrib command with +r option
will make the file a.txt as read-only. As the compiler could not write to it,
it generates the above error. The compiler would rather gives us an error than
change the attribute. The above set of instructions demonstrated the need for
error number CS2012.
>csc /target:library
a.cs /baseaddress:ui
Compiler Error
error CS2013: Invalid image base number 'ui'
Whenever we build a dll we can
specify where the dll is to be loaded in memory. This is done using the
/baseaddress option which demands a number in hex. As we didn't fulfil its
needs, we are returned an error. The baseaddress is always specified by
default, if we do not specify one.
>csc a.exe
Compiler Error
error CS2015: 'C:\csharp\a.exe' is a binary file instead of a
source code file
error CS1504: Source file 'C:\csharp\a.exe' could not be
opened ('Unspecified error ')
We need to give the compiler a
source file consisting of a program and not a binary file. The second error is
a natural corollary to the first as it could not open the file. These two
errors go hand and glove with each other.
>csc a.cs /codepage:890
Compiler Error
fatal error CS2016: Code page '890' is invalid or not
installed
A codepage has to do with
different languages and your machine has to have the particular code page
installed on it before you can use it.
>csc /nologo /target:library /main:zzz a.cs
Compiler Error
fatal error CS2017: Cannot specify /main if building a module
or library
Nobody likes contradictions. A
library or a dll is a very different animal than an exe file. You can have
either one or the other never both. We are first ask the compiler to build a
dll and then specify the class that contains the entrypoint function Main. As
main is valid only in an exe file, the error is reported
The next error message in
sequence CS2018 points to a file called cscmsgs.dll for all the error messages.
This file does not exist on our computer.
>csc /nologo /target:jjj a.cs
Compiler Error
fatal error CS2019: Invalid target type for /target: must specify
'exe', 'winexe', 'library', or 'module'
We can only build four types of
output files with this version of the compiler. We asked the compiler to build
the wrong type of target, hence the error.
Compiler Error
fatal error CS2021: File name 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
aaaaaaaaaaaaaaaaaaaaaaaaaaaa.cs' is too long or invalid
fatal error CS2008: No inputs specified
There is a variable/MACRO called
MAX_PATH which has a value of 260. If our file name exceeds this size we will
get an error CS2021. The compiler was asked to compile a file with a very long
name, since the name was too long, the error gets reported. We have gone to
extents to display every error!
a.cs
[assembly:System.CLSCompliant(true)]
public class zzz
{
internal void abc(__arglist)
{
}
public void pqr(__arglist)
{
}
}
Compiler Error
a.cs(7,13): error CS3000: Methods with variable arguments are
not CLS-compliant
CLS stands for Common Language
Specification and is the thingy that makes sure that a class created in Cobol
can have a function added in Perl. Also it can be a base class for a class in
Visual Basic and be finally be called in C# or ASP.Net. To make sure that all
our code is CLS compliant, the above attribute shown above is to be applied to
the class. Only those functions that are not private or public can accept a
variable number of arguments. Thus, the abc function being internal does not
give an error whereas pqr does.
a.cs
[assembly:System.CLSCompliant(true)]
public class zzz
{
internal void abc(ushort i)
{
}
public void pqr(ushort i)
{
}
}
Compiler Error
a.cs(7,17): error CS3001: Argument type 'ushort' is not
CLS-compliant
The ushort data type is not CLS
compliant which means that all languages that are .NET compliant do not have to
support it. Like above, the rule applies only to private or public members.
a.cs
[assembly:System.CLSCompliant(true)]
public class zzz {
public ushort pqr()
{
return 0;
}
}
Compiler Error
a.cs(4,8): error CS3002: Return type of 'zzz.pqr()' is not
CLS-compliant
The return type cannot be a
ushort in a CLS compliant class. In other words, the ushort data type cannot be
used anywhere.
a.cs
[assembly:System.CLSCompliant(true)]
public class zzz
{
public void pqr()
{
ushort j;
}
public ushort i;
}
Compiler Error
a.cs(6,8): warning CS0168: The variable 'j' is declared but
never used
a.cs(8,15): error CS3003: Type of 'zzz.i' is not CLS-compliant
We need to slightly modify the
above statement. Variables created on the stack or local variables cannot be
marked with an access modifier. Thus, public instance variables cannot be
declared as ushort whereas local since they are not visible outside the
function.
a.cs
[assembly:System.CLSCompliant(true)]
public class zzz {
public int a1;
public int A1;
}
Compiler Error
a.cs(5,12): error CS3005: Identifier 'zzz.A1' differing only
in case is not CLS-compliant
The C# programming language may
be case sensitive but CLS languages may not be. Thus when we write code which
is CLS complaint, we make sure we are also case insensitive.
a.cs
[assembly: System.CLSCompliant(true)]
public class zzz
{
public int _a ;
}
Compiler Error
a.cs(4,12): error CS3008: Identifier 'zzz._a' is not
CLS-compliant
There may be millions of
programming languages out there, which some day will be .NET compatible. Some
of them may have a special meaning for the underscore character. Thus, the CLS
forbids an underscore in the name of a variable.
a.cs
[assembly:System.CLSCompliant(true)]
public interface iii
{
[System.CLSCompliant(false)]
void abc();
}
Compiler Error
a.cs(5,7): error CS3010: 'iii.abc()': CLS-compliant interfaces
must have CLS-compliant members
It does not make sense for the
entire interface to be CLS compliant other than one function in it. Even if a
single member is not CLS compliant, then the entire interface becomes CLS
non-compliant.
a.cs
[assembly: System.CLSCompliant(true)]
public abstract class iii
{
[System.CLSCompliant(false)]
public abstract int abc();
}
Compiler Error
a.cs(5,21): error CS3011: 'iii.abc()': non CLS-compliant
members cannot be abstract
Programming languages the world
over may not have all the sophistication as in C#. The CLS specification is a
simpler and easier C#. Therefore a large number of features in C# are not
implemented in the CLS. Remember, C# is today arguably one of the world's most
powerful languages. One of the feature supported in C# and not a CLS compliant
is the notion of abstract. Hence, the above error. The CLS is a subset of the
C# language specification.
a.cs
[module:System.CLSCompliant(true)]
public class zzz
{
public static void Main() {
}
}
Compiler Error
a.cs(1,9): warning CS3012: You must specify the CLSCompliant
attribute on the assembly, not the module, to enable CLS compliance checking
The error message says it all.
You cannot specify the above attribute on a module.
a.cs
[assembly:System.CLSCompliant(false)]
public class iii
{
[System.CLSCompliant(true)]
public void abc()
{
}
}
Compiler Error
a.cs(4,2): error CS3014: 'iii.abc()' cannot be marked as CLS
compliant because the assembly is not marked as compliant
Just as we had some lines
earlier, we cannot have a class which is CLS compliant and a single member
within it which is non-CLS compliant. One rotten apple spoils the entire lot.
a.cs
[assembly:System.CLSCompliant(true)]
public class zzz : System.Attribute
{
public zzz(int[] i)
{
}
}
Compiler Error
a.cs(2,14): error CS3015: 'zzz' has no accessible constructors
which use only CLS compliant types
At the outset, we need one
constructor that is CLS complaint. Here we have only one construct but it is
not CLS complaint as arrays are not part of the allowed data types in a method
call.
a.cs
class zzz
{
public static void Main()
{
System.Collections.ArrayList a = new
System.Collections.ArrayList();
System.Console.WriteLine(a.Item[0]);
//
Console.WriteLine("First Element is {0}", a.[0]);
}
}
Compiler Error
a.cs(6,26): error CS0117: 'System.Collections.ArrayList' does
not contain a definition for 'Item'
When using indexed properties
like those in the ArrayList, we do not have to complicate life. The ArrayList
object is called a. To access its member, in place of a.Item[0], a simple a.[0] will do.
Nothing complicated here. We do
not have to use the Item specifier at all.
We can never ever show you a an
error check for CS0174 as it occurs whenever we recompile System.Object. We do
not have the source code for it and hence we cannot compile it. It is the only
class that does not have any base class at all!
a.cs
public class zzz
{
public static void Main ()
{
lock (1)
{
}
}
}
Compiler Error
a.cs(5,1): error CS0185: 'int' is not a reference type as
required by the lock statement
The lock statement requires a
reference type for it to perform its job. The parameter cannot be an int or a
value type, hence the error. The lock statement works only on reference types.
We hate functions as they are so
boring. They insist that we always pass them the same number of parameters.
There is a way out to make sure that functions are allowed to receive a
variable number of parameters. To accomplish this task, the keyword __arglist
is incorporated. N number of parameters can be given then.
__arglist used as a parameter
name in the function then contains a reference to the variable number of
arguments. To access the values, we create an object that looks like
ArgIterator with the __arglist as a parameter. The GetRemainingCount function
within this object returns the count of parameters and each parameter is then
retrieved using the GetNextArg member of the ArgIterator.
The values can be converted to an
int using __refvalue. If we do not then we will get a System.TypedReference
instead of the actual value. This is how we can pass a variable number of
parameters to a function.
a.cs
public class zzz {
public static void abc (int a)
{
object o = __arglist;
}
}
Compiler Error
a.cs(5,12): error CS0190: The __arglist construct is valid
only within a variable argument method
You can only use a __arglist
construct in methods, which will accept a variable number of arguments.
a.cs
public class zzz
{
public unsafe static void Main ()
{
int *i = null;
int j = 0;
j = i[1,2];
}
}
>csc a.cs /unsafe
Compiler Error
a.cs(7,5): error CS0196: A pointer must be indexed by only one
value
The array brackets are only a
notation. They internally get converted into a pointer. Thus i[2] internally
becomes *(i+2). Thus, we can never have multiple indices for a pointer. Unlike
C, at one level the C# programming language and its faithful agents do not
understand the meaning of an array.
a.cs
public class zzz
{
unsafe public static void Main ()
{
zzz** a = null;
foreach (zzz x in a)
{
}
}
}
Compiler Error
a.cs(6,1): error CS1579: foreach statement cannot operate on
variables of type '' because '' does not contain a definition for
'GetEnumerator', or it is inaccessible
The variable a is a pointer to a
pointer to a zzz. This means that variable a contains the address of another
variable which in turn contains the address of an object that looks like
zzz.
The foreach statement does not
understand objects completely. It requires certain functions to be present in
the object for it to successfully enumerate all of them.
a.cs
public class zzz
{
unsafe public int i
{
unsafe set {}
}
}
Compiler Error
a.cs(5,1): error CS1609: Modifiers cannot be placed on
property or event accessor declarations
A property is superior to its get
and set accessors. If the property is made unsafe then it is common knowledge
that the accessors will also be unsafe. We have realized by now that the
compiler does not like us stating the obvious and hence adding the keyword
unsafe on the set accessor will bring about the above error.
a.cs
public class zzz
{
unsafe public static void Main()
{
yyy a = new yyy();
yyy *b;
b = &a;
}
}
class yyy
{
}
Compiler Error
a.cs(6,5): error CS0208: Cannot take the address or size of a
variable of a managed type ('yyy')
a.cs(7,5): error CS0208: Cannot take the address or size of a
variable of a managed type ('yyy')
A two-in-one error. A combo at
last! The concept of pointers existed in the C programming language, which did
not understand classes let alone managed types. Thus, pointers are best left
alone to deal with values types and not managed types. We cannot figure out
their addresses in memory nor their size. A lot about managed types are best
handled internally by the compiler and are beyond our understanding. Like the
secret services, we cannot know everything.
a.cs
public class zzz {
unsafe public static void Main()
{
fixed (int i)
{
}
}
}
Compiler Error
a.cs(4,8): error CS0209: The type of locals declared in a
fixed statement must be a pointer type.
a.cs(4,12): error CS0210: You must provide an initializer in a
fixed or using statement declaration
The garbage collector, if allowed
to move objects in memory, would make the pointer values meaningless. Hence, we
use the fixed statement to pin down a variable in memory while the code is
executing. We mark these objects as special using the statement fixed as we
want to prevent the garbage collector from moving objects holding addresses
around in memory. It is obvious that addresses can only be stored by a pointer
and not by any other variable. A fixed keyword is applicable only on pointers.
a.cs
public class zzz
{
unsafe public static void Main()
{
fixed (int* i)
{
}
}
}
Compiler Error
a.cs(5,13): error CS0210: You must provide an initializer in a
fixed statement declaration
Assuming we do use a pointer in a
fixed statement, our problems are not yet over. We have to initialize this
pointer to an object or any other value including null as in int *i = null. We
are not allowed to take the address of a managed object anywhere else except in
a fixed statement. The {} brackets is the range for which the garbage collector
promises not moving around as the objects has been pinned.
a.cs
public class zzz
{
unsafe public void Main()
{
int j = 0;
int *i = &(j
+ 20);
}
}
Compiler Error
a.cs(6,10): error CS0211: Cannot take the address of the given
expression
a.cs(6,10): error CS0212: You can only take the address of
unfixed expression inside of a fixed statement initializer
Not everything in life has an
address. Only variables have an address. The expression j+20 has no address as
it does not represent a unique memory location. Thus, we can only give i= and
use the & in front of entities that are stored in memory.
a.cs
public class yyy {
public int i= 0;
}
public class zzz
{
unsafe public static void Main()
{
yyy a = new yyy();
int *j = &a.i;
}
}
Compiler Error
a.cs(8,10): error CS0212: You can only take the address of
unfixed expression inside of a fixed statement initializer
There are certain rules to be
followed in an unsafe context. The object a is an instance of class yyy and
this makes it a managed object. Its address can only be taken in a fixed
statement and not anywhere else.
a.cs
public class yyy
{
public int i= 0;
}
public class zzz
{
unsafe public static void Main()
{
yyy a = new yyy();
fixed ( int *j= null)
{
j = &a.i;
}
}
}
Compiler Error
a.cs(10,14): error CS0213: You do not need to use the fixed
statement to take the address of an already fixed expression
a.cs(12,5): error CS0212: You can only take the address of
unfixed expression inside of a fixed statement initializer
a.cs(12,1): error CS1604: Cannot assign to 'j' because it is
read-only
We explicitly said & inside a
fixed statement and not in the range of the fixed. The only way out of a
nagging compiler is as follows.
a.cs
public class yyy {
public int i= 0;
}
public class zzz
{
unsafe public static void Main()
{
yyy a = new yyy();
fixed ( int *j= &a.i)
{
}
}
}
No errors at last. A huge sigh of
relief!
a.cs
public class zzz
{
unsafe public static void Main()
{
int i = 0;
fixed (int *j = &i)
{
}
}
}
Compiler Error
a.cs(6,17): error CS0213: You do not need to use the fixed
statement to take the address of an already fixed expression
Value types like an int are
created on the stack. Their positions in memory cannot change for the entire
duration of the function. At the end of the function they die. The garbage
collector cannot move them around in memory at all for optimizing your code to
make it run faster. Thus, if you take the address of a local variable in a
fixed statement, the compiler throws an error at you for doing the obvious.
a.cs
public class zzz {
public void abc(params int[] a, __arglist)
{
}
}
Compiler Error
a.cs(2,17): error CS0231: A params or __arglist parameter must
be the last parameter in a formal parameter list
We cannot have life the way we
want. The params and __arglist allow us to invoke a function with a variable
number of arguments. We have to choose on one of them. We cannot choose both as
the compiler will not know where one starts and the other gets over. This
cannot be called a restriction ever.
a.cs
delegate int ddd(__arglist);
Compiler Error
a.cs(1,14): error CS0235: __arglist is not allowed in
delegates
We are allowed to use the params
keyword in a delegate if we want it to accept a multiple number of arguments.
We cannot implement the same concept by using __arglist instead as it has
fallen out of favor with the compiler. It is a simple rule that the compiler
likes, so do we.
a.cs
[System.Runtime.InteropServices.ComImport]
public class a
{
}
Compiler Error
a.cs(1,57): error CS0596: The Guid attribute must be specified
with the ComImport attribute
The attribute called ComImport
lets you specify a class as an ActiveX object. Every ActiveX object is known by
a 16 byte or a 128 bit number called its GUID or Globally Unique Identifier. We
forget to specify this 16 byte number and hence our ActiveX object was only
known by its name and not its number, which is an error.
a.cs
using System.Runtime.InteropServices;
[ComImport, Guid("vijay")]public class a
{
}
Compiler Error
a.cs(2,13): error CS0647: Error emitting
'System.Runtime.InteropServices.GuidAttribute' attribute --
'Incorrect uuid format.'
No programming language as of now
can represent a 16 byte number directly. We have a structure called GUID which
represents this 16 byte number. We have to represent this 16 byte number is a
certain way which looks like: Guid("1234abcd-a234-abcd-1111-678987654678"). Since the program does not follow the rules,
an error is reported
a.cs
public class zzz
{
[System.Runtime.InteropServices.DllImport("USER32.DLL")]
extern int MessageBox(int a);
}
Compiler Error
a.cs(3,2): error CS0601: The DllImport attribute must be
specified on a method marked 'static' and 'extern'.
The DllImport attribute informs
the compiler that the code of the function MessageBox is in a dll file called
user32.dll. As we have not created this function and the code too is not
present in the file, we have to signify that it is static and extern. We need
both modifiers, one alone will not suffice.
a.cs
using System.Runtime.InteropServices;
public class zzz
{
[DllImport("kernel32.dll")]
public static extern int abc();
}
The attributes DllImport applies to static and extern functions
only.
a.cs
using System;
using System.Runtime.CompilerServices;
public class yyy
{
[IndexerName("vijay")]
public int this[int i]
{
set { }
}
}
public class zzz : yyy
{
[IndexerName("vijay")]
public override int this[int i] {
set { }
}
}
Compiler Error
a.cs(12,2): error CS0609: Cannot set the IndexerName attribute
on an indexer marked override
You can be extremely selective
the code that should access the attributes. The attribute called IndexerName
cannot be used on an indexer, which is override but can be used on the indexer
in class yyy.
a.cs
using System;
public class yyy : Attribute {
int i;
}
[yyy(i=0)]
class zzz {
}
Compiler Error
a.cs(5,6): error CS0617: 'i' is not a valid named attribute
argument. Named attribute arguments must be fields which are not readonly,
static or const, or properties with a set accessor which are not static.
There is no way that we can use
the private members of an attribute class. The member i is private in class yyy
and hence can only be used if we use the access modifier public in front of it.
The error also tells us about the named arguments that can be used. At times,
these error messages are not bad guys and can be helpful at times.
a.cs
using System;
public class yyy
{
[Obsolete("vijay mukhi", false)]
public static void abc()
{
}
}
class zzz
{
public static void Main()
{
yyy.abc();
}
}
Compiler Warning
a.cs(13,1): warning CS0618: 'yyy.abc()' is obsolete: 'vijay
mukhi'
We have placed the Obsolete tag
in front of the function abc. The warning message vijay mukhi is only displayed
if we access function abc. Remember it is not an error but an aid to inform the
user not to use a certain function as they maybe discontinued in the future
versions.
Change the false in the attribute
to true as follows
[Obsolete("vijay mukhi", true)]
Compiler Error
a.cs(13,1): error CS0619: 'yyy.abc()' is obsolete: 'vijay
mukhi'
All that happens is that the
warning message gets converted to an error. You decide on how serious it is if
we use a certain function which may get obsolete very soon.
a.cs
public class zzz {
System.TypedReference i;
}
Compiler Error
a.cs(2,1): error CS0610: Field or property cannot be of type
'System.TypedReference'
The class TypedReference is
special and cannot be used to create a field but can be used as parameters to a
method.
a.cs
public class zzz
{
System.TypedReference[] i = new System.TypedReference[1];
}
Compiler Error
a.cs(3,23): error CS0611: Array elements cannot be of type
System.TypedReference
An array type cannot also be a
TypedReference.
a.cs
public class zzz
{
static extern public void abc();
}
Compiler Error
a.cs(3,27): warning CS0626: Method, operator, or accessor
'zzz.abc()' is marked external and has no attributes on it. Consider adding a
DllImport attribute to specify the external implementation
An extern method should have an
attribute of DllImport. This specifies the dll file containing the
implementation of the function. We expected an error and got a warning instead.
The world was never a predictable place to stay in!
a.cs
using System;
[Obsolete("Vijay",IsError=false)]
interface iii
{
}
public class zzz
{
public static void Main ()
{
object[] a = typeof(I1).GetCustomAttributes();
Console.WriteLine (((ObsoleteAttribute)a[0]).IsError);
}
}
Compiler Error
a.cs(2,19): error CS0632: 'IsError' : Named attribute argument
can't be a read only property
An attribute can have read only
properties and they cannot be use as named arguments. The above error takes
place as IsError is a readonly property in the attribute obsolete and we are
trying to fetch its value in the WriteLine function.
a.cs
using System;
using System.Runtime.CompilerServices;
public class zzz
{
[IndexerName("vijay mukhi")]
public int this[int j]
{
set {}
}
}
Compiler Error
a.cs(4,7): error CS0633: argument to IndexerName attribute
must be a valid identifier
The name attribute names the
indexer. We gave an invalid name of vijay mukhi, it has a space in it. Remove
the space and the error goes away. The name must follow all the rules of a
valid identifier.
a.cs
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
struct zzz
{
[FieldOffset(40)]
public int i;
}
Compiler Error
a.cs(5,2): error CS0636: FieldOffset attribute can only be
placed on members of type marked with the StructLayout(LayoutKind.Explicit)
The FieldOffset attribute
specifies where each field will appear in memory. We have a complete control
over the layout of the structure. The only condition is that we need to use the
LayoutKind as Explicit and not as Sequential.
a.cs
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Explicit)]
struct zzz
{
[FieldOffset(40)]
public static int i;
}
Compiler Error
a.cs(5,2): error CS0637: The FieldOffset attribute not allowed
on static or const fields
One more restriction on the
attribute FieldOffset is that we cannot use it on static or const fields as the
compiler would like to decide where to place them in memory.
a.cs
[abc:vijay]
class zzz
{
}
Compiler Error
a.cs(1,6): error CS0658: 'abc' is not a valid attribute
location
Here, abc is any arbitrary name
that we have chosen, hence the error is reported.
a.cs
using System;
[AttributeUsage(AttributeTargets.All)]
public class zzz
{
}
Compiler Error
a.cs(2,2): error CS0641: 'AttributeUsage' : attribute is only
valid on classes derived from System.Attribute
The class AttributeUsage is used
to inform the compiler where the attribute class can be used. Thus the class
following must be derived from System.Attribute to qualify as an attribute
class. If you do not follow the above rules, you will get saddled with the
above error.
a.cs
[System.Reflection.DefaultMemberAttribute("viajy")]
class zzz
{
public int this[int i]
{
set {}
}
}
Compiler Error
a.cs(1,2): error CS0646: Cannot specify the DefaultMember
attribute on type containing an indexer
Any class that is tagged with a
DefaultMemberAttribute cannot be used with a class that contains an indexer.
Strange are the ways of the world at first sight.
Note: Xml warnings are only
generated if you use the /doc: option along with the compiler i.e. csc a.cs
/doc:a.xml
a.cs
public class zzz
{
public static zzz operator / (zzz a1, zzz a2)
{
return null;
}
/// <seealso cref="zzz.operator@"/>
public static void Main()
{
}
}
Compiler Warning
a.cs(1,14): warning CS1591: Missing XML comment for publicly
visible type or member 'zzz'
a.cs(3,19): warning CS1591: Missing XML comment for publicly
visible type or member 'zzz.operator /(zzz, zzz)'
a.cs(7,33): warning CS1003: Syntax error, '"' expected
a.cs(7,32): warning CS1039: Unterminated string literal
a.cs(7,32): warning CS1037: Overloadable operator expected
a.cs(7,20): warning CS1584: XML comment on 'zzz.Main()' has
syntactically incorrect cref attribute 'zzz.operator@'
The compiler found an invalid
link with ///. The operator statement was wrong as it did not specify the
correct operator.
>csc a.cs /nologo /resource:a.bmp
Compiler Error
error CS1566: Error reading resource file 'C:\csharp\a.bmp' --
'The system cannot find the file specified. '
This error takes place when the
compiler cannot find the specified filename.
>csc a.cs /nologo /resource:a.bmp,aa /resource:b.bmp,aa
Compiler Error
error CS1508: Resource identifier 'aa' has already been used
in this assembly
We copied two files a.bmp and
b.bmp in our current subdirectory. Using the /resource option, we can specify a
name for the resource. We gave the same name and hence we received an error.
a.cs
#if aa
#endif
#if !aa
#endif
#if (aa)
#endif
#if true
#endif
#if false
#endif
#if 1
#endif
#if ~aa
#endif
#if *
#endif
Compiler Error
a.cs(11,5): error CS1517: Invalid preprocessor expression
a.cs(13,5): error CS1517: Invalid preprocessor expression
a.cs(15,5): error CS1517: Invalid preprocessor expression
The last three preprocessors
directives gave us an error as we cannot use a number, the ~ sign or a * to the #if. True and false
are ok and so are () etc.
>csc a.cs /warn:100
Compiler Error
error CS1900: Warning level must be in the range 0-4
There are only five warning
levels, starting from zero. Depending upon the warning number used, we will see
certain types of warnings. The rest will be suppressed.
>csc a.cs /warn:0
/warnaserror
Compiler Error
error CS1901: Conflicting options specified: Warning level 0; Treat warnings as errors
/warn:0 turns the warnings off
and /warnaserror treats warnings as errors. The compiler thinks we are drunk,
hence it tries to clarify things about these two mutually exclusive options.
>csc a.cs /reference:\charpbook
Compiler Error
error CS0006: Metadata file '\charp' could not be found
We have to specify the name of a
file not a subdirectory.
>csc a.cs /reference:\
Compiler Error
error CS1541: Invalid include option: '\' -- cannot include
directories
We have to give some compiler
options an actual file name. Names of sub-directories are not allowed.
a.cs
class zzz {
}
>csc a.cs /main:zzz
Compiler Error
a.cs(1,7): error CS1558: 'zzz' does not have a suitable Main
method
The /main option specifies which
class contains the method main. If we had two .cs files and each contained the
Main function, the /main option informs the compiler about the file it should
consider having the entry point.
>csc a.cs /main:zzzz
Compiler Error
error CS1555: Could not find 'zzzz' specified for Main method
The /main option has to be
supplied with the name of a class that exists in the .cs files. Common sense.
class zzz {
}
Compiler Error
a.cs(1,7): error CS1558: 'zzz' does not have a suitable Main
method
The /main compiler option
specifies the class containing the function Main. We we so absent-minded that
we forget to write one in the class zzz,
hence the compiler comes back with the relevant error.
a.cs
#line 12
"abccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
Compiler Error
a.cs(1,11): error CS1560: Filename specified for #line is too
long
The name of the file in the #line
directive cannot exceed 256 characters. We exceeded the limit.
>csc /nologo /win32res:a.res /win32icon:a.ico
Compiler Error
error CS1565: Conflicting options specified: Win32 resource file; Win32 icon
A res file stores various
resources like images, sound files, menus, icons etc. in a compiled form. An
.ico file can be used to store an icon exclusively too. The above two options
hate each other and thus cannot be given together.
>attrib +r a.xml
>csc /nologo /doc:a.xml a.cs
Compiler Error
error CS1569: Error generating XML documentation file 'a.xml'
('Access is denied. ')
We made the file a.xml read only
and as the /doc option could not write to the file we receive the above error.
a.cs
// the following line generates CS1570
/// <summary> returns true if < 5 </summary>
public class zzz
{
}
Compiler Warning
a.cs(2,32): warning CS1570: XML comment on 'zzz' has badly
formed XML -- 'Whitespace is not allowed at this location.
XML has its own set of rules. We are not allowed to use the <
sign in the /// tags. We have to use < instead. There are a large number
of ways to create ill formed XML and any badly formed XML will generate the
above error. Thus, even in the comments someone is checking what you are doing.
a.cs
public class zzz
{
/// <param name='aa'>Used to indicate status.</param>
/// <param name='aa'>Used to indicate status.</param>
public static void Main (string [] aa)
{
}
}
Compiler Warning
a.cs(4,18): warning CS1571: XML comment on
'zzz.Main(string[])' has a duplicate param tag for 'aa'
Nobody likes being told to do
something twice. Even in a /// tag! The param denotes a parameter to a
function, so, we cannot have two parameters with the same name in a method.
a.cs
public class zzz {
/// <param name='aaa'>Used to indicate
status.</param>
public static void Main (string [] aa)
{
}
}
Compiler Warning
a.cs(3,18): warning CS1572: XML comment on
'zzz.Main(string[])' has a param tag for 'aaa', but there is no parameter by
that name
a.cs(4,20): warning CS1573: Parameter 'aa' has no matching
param tag in XML comment (but other parameters do)
The first warning is very clear.
Our function Main accepts a parameter called aa and in the XML tag we have
given the name as aaa. The second warning is that the function name has a
parameter called aa and we do not have a param tag it.
a.cs
/// <exception cref="System.Console.WriteLin">An
exception class.</exception>
class zzz : System.Exception
{
}
Compiler Warning
a.cs(1,22): warning CS1574: XML comment on 'zzz' has cref
attribute 'System.Console.WriteLin' that could not be found
The compiler checks every move of
yours. The cref attribute needs a valid method name WriteLine is not spelt
right as the last e is missing, hence the error.
a.cs
/// <seealso cref="abc(i)"/>
public class zzz
{
public void abc(int i)
{
}
public void abc(char i)
{
}
}
Compiler Warning
a.cs(1,20): warning CS1580: Invalid type for parameter '1' in
XML comment cref attribute
a.cs(1,20): warning CS1574: XML comment on 'zzz' has cref
attribute 'abc(i)' that could not be found
The cref also takes a data type
for the parameters to a function, not the name of the parameter. Here, we could
specify a int or a char but not the name of the parameter i.
a.cs
public class zzz
{
public static explicit operator int(zzz f)
{
return 0;
}
}
/// <seealso cref="zzz.explicit operator intt(zzz)"/>
public class yyy
{
}
Compiler Warning
a.cs(1,14): warning CS1591: Missing XML comment for publicly
visible type or member 'zzz'
a.cs(3,15): warning CS1591: Missing XML comment for publicly
visible type or member 'zzz.explicit operator int(zzz)'
a.cs(8,20): warning CS1581: Invalid return type in XML comment
cref attribute
The name of the operator is int
and not intt. Be careful while typing the name.
a.cs
public class zzz
{
/// <remarks>
Called in <see cref="zzz::Main"/> </remarks>
public static void Main()
{
}
}
Compiler Warning
a.cs(3,40): warning CS1036: ( or . expected
a.cs(3,37): warning CS1584: XML comment on 'zzz.Main()' has
syntactically incorrect cref attribute 'zzz::Main'
The XML tag must have everything
prim and proper. The separator between the class name and function name is a .
and not a ::. Have to be careful what we do in front of a computer!
Csc /nologo a.cs /win32res:a.xml
Compiler Error
error CS1583: 'C:\csharp\a.xml' is not a valid Win32 resource
file
A res file has a certain file
format that is documented on the Microsoft web site. We gave a text file
instead. The compiler checks the validity of a res file before reading it.
a.cs
public class zzz
{
unsafe public static void Main() {
int *p = stackalloc int (30);
}
}
Compiler Error
a.cs(4,25): error CS1575: A stackalloc expression requires []
after type
The stackalloc keyword is used to
allocate memory for us. It has the array syntax and not the function syntax.
The [] brackets are mandatory for this function and not the ().
>csc /nologo a.cs /R:a.ico
Compiler Error
fatal error CS0009: Metadata file 'C:\csharp\a.ico' could not
be opened -- 'File is corrupt'
An .dll file has a predefined
file format called the PE or Portable Executable file format. A .ico file
format is very different from the PE format. We can not mix up file formats in
compiler options.
a.cs
public class zzz
{
public static void Main()
{
}
}
>csc a.cs
a2.cs
public class yyy : zzz
{
public static void Main()
{
}
}
csc a2.cs /r:a.exe
a3.cs
class xxx : yyy
{
public static void Main()
{
}
}
csc a3.cs /r:a2.exe gives the error
Compiler Error
a2.exe: error CS0011: Referenced class 'yyy' has base class or
interface 'zzz' defined in an assembly that is not referenced. You must add a reference to assembly 'a'.
We come across a slight
roadblock. The file a.exe contains a class zzz and a2.exe contains class yyy.
When we compile a3.cs with the /r: option alongwith a2.exe as it contains class
yyy, we get an error. A.exe should have also been stated as it contains the
code for zzz which yyy is derived from. Thus to remove the error we should
restate the command as
>csc a3.cs /r:a2.exe;a.exe
a.cs
class yyy
{
}
public class zzz
{
public yyy y;
}
Compiler Error
a.cs(6,12): error CS0052: Inconsistent accessibility: field
type 'yyy' is less accessible than field 'zzz.y'
As a re-revision, we are not
allowed to use the class yyy in class zzz as a public variable because the
class is declared internal by default. The member y cannot be more accessible
than the class yyy that is internal. As
y is declared public, the error pops up. Change it to a less accessible
modifier like private or internal and the error simply vanishes. If the class
yyy is made public then none of the above problems would arise. You can easily
become less important than you really are but cannot aspire to greater heights.
>attrib +r a.exe
>csc a.cs
Compiler Error
error CS0016: Could not write to output file 'a.exe' --
'Access is denied. '
As the file a.exe is marked as
read only, when the compiler tries to write the new output file it came back
with the above operating system error.
The compiler command given as
>csc /out:a.exe
a.cs /incremental
creates a file called a.exe.incr
in the same sub-directory. This file contains information to speed up the
compilation process. So far we have been using only one or two files that carry
our code. In a real-life situation we will have over a thousand files. Each
time we run the compiler we do not need all the files to be recompiled but only
those functions that have changed since the last time we compiled. This speeds
up the entire process as most files will not be recompiled again. This
information on the new changes in a function must be stored at someplace. That
file is a .incr file. We will display the first line of this file.
a.exe.incr
Incremental Build Data for C# Compiler -- this file stores
data to enable fast rebuilds.
>attrib +r a.exe.incr
>csc /out:a.exe
a.cs /incremental
Like before we made the file
cool.incr read only.
error CS0032: Could not open incremental build file
'C:\csharp\a.exe.incr' for writing
>csc a.cs /debug
This creates a file called a.pdb,
which is approx 12K large. This file contains debugging information. Whenever
programs do not work, a debugger is used to point out the exact location of the
error and the reasons behind it. A computer detectives first tool is debugger
and no self respecting computer professional travels without one always.
>attrib +r a.pdb
Compiler Error
fatal error CS0042: Unexpected error creating debug
information file 'a.PDB' -- 'a.pdb: Access is denied.
>csc /target:module /out:a.dll a.cs
The /target option builds a dll
file named a.dll and not an executable. A dll traditionally contains code and
cannot be executed at all.
>csc b.cs /R:a.dll
Produces
Compiler Error
error CS1509: Referenced file 'C:\csharp\a.dll' is not an
assembly; use '/addmodule' option instead
The error goes away when the
command is written
>Csc b.cs /addmodule:a.dll
Any file specified in a dll has
to internally carry an assembly manifest. Using /addmodule, we want to add only
the metadata information for a.dll to the assembly of the current program. It
does not add the assembly of a.dll to the assembly of the current program.
>csc /target:library a.cs
Produces a.dll
Csc /addmodule:a.dll b.cs
Produces the following error.
Compiler Error
error CS1542: 'C:\csharp\a.dll' cannot be added to this
assembly because it already is an assembly; use '/R' option instead
Anything produced by /target can
only be used with a /reference and not by /addmodule.
We have an extremely versatile
compiler with us. If we run as
>csc /target:exe a.cs /target:module b.cs
It will create only one file,
i.e. an exe file
>csc /target:exe a.cs /target:exe b.cs
Produces
Compiler Error
error CS2020: Only the first set of input files can build a
target other than 'module'
The first /target can be either an exe or a winexe or a library. The remaining files can only have only a /target:module. This is more for a multi-output compilation.