Undocumented compiler error CS0226

This one’s an obvious error really – but it’s still undocumented, and thus qualifies for a blog entry. I guess once __arglist was dropped from the standard documentation, all its associated error messages were dropped too.

Compiler Error CS0226

Error Message

An __arglist expression may only appear inside of a call or new expression


The following sample generates CS0226

// error CS0226
__arglist("apples", "pears");

Expected usage
static void Foo(Object obj, __arglist)
    Console.WriteLine("First arg : {0}", obj);

    ArgIterator iterator = new ArgIterator(__arglist);
    for (int i = iterator.GetRemainingCount(); i > 0; i--)

. . .

Foo(x, __arglist("apples", "pears"));

C++/CLI bug : Operator overloading in an interface

There was a very interesting thread on Code Project’s C++/CLI forum last week. Here’s the link to the thread :

The gist of the post is that the C++/CLI compiler was not recognizing an overloaded unary operator defined in an interface while it could do so when the interface was changed to a base class.

Here’s some example code that reproduces the problem :

 interface class Base
  static int operator * (Base^) { return 99; }
  static int operator + (Base^) { return 99; }

 ref class Derived : Base

  static void Foo()
    Derived^ d = gcnew Derived();

    int x = *d;
    int y = +d; 

Both those lines will not compile. In the case of the * operator you get a confusing error because the compiler assumes you are trying to dereference the handle.

Error 1 error C2440: 'initializing' : cannot convert from
    'Test::Derived' to 'int'
Error 2 error C2675: unary '+' : 'Test::Derived ^' does not define this
    operator or a conversion to a type acceptable to the predefined

Changing Base from an interface class to a ref class works fine. I believe this is a compiler bug because the ECMA language specification says this in section 25.2 Interface members:

“An interface definition can declare zero or more members. The members of an interface shall be static data members, instance or static functions, a static constructor, instance or static properties, instance or static events, operator functions, or nested types of any kind. An interface shall not contain instance data members, instance constructors, or a finalizer.”

The workaround right now is to do this :

int x = Base::operator *(d);
int y = Base::operator +(d);
Affected versions:

This bug exists in VS 2008 as well as in VS 2010 RC.

Undocumented compiler error CS0224

A fellow CPian leppie had posted about an undocumented C# error he got (error CS0224) and asked if anyone could reproduce the error (back in Dec 2009). For fun I played with the compiler and managed to reproduce the error. That gave me the idea of blogging about this and other such undocumented errors. Of course the moment I blog about it, it ceases to become undocumented by definition. Also by undocumented, I mean undocumented on MSDN. It may have been blogged on or written about elsewhere, though I do intend to use Google and Bing to try and make sure it’s not a commonly known error. I start off with leppie’s error of CS0224.

As of today (Feb 26, 2010) VS 2008’s MSDN documentation jumps from CS0221 to CS0225, and VS 2010’s MSDN documentation jumps from CS0201 to CS0229. I don’t know why VS 2010 decided to drop those extra error codes, but then this is the RC documentation, and maybe the RTM version will add back those that were documented in VS2008. Anyway enough with the talk and on to the error.

Compiler Error CS0224

Error Message

A method with vararg cannot be generic, be in a generic type, or have a parameter array


The following sample generates CS0224

// error CS0224
static void Foo<T>(T t, __arglist) { }

Correct way

You could rewrite the method in one of the following two ways to get the equivalent functionality :

static void Foo<T>(T t, params object[] args) { }


static void Foo(Object obj, __arglist)  { }