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 &lt; 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.