473,395 Members | 1,679 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

When Overloading the Plus Operator, What are Valid Arguments Types?

Hello:

Today I learned that the + operator cannot be passed a delegate. I get
an error from the CLR saying I have an invalid program.

With that, I was wondering if someone could tell me what other types I
am not allowed to make parameters.

Thanks,
Travis

class Failer
{
public static Failer operator +(Failer failer,
MulticastDelegate handler)
{
return failer;
}

public static void Test()
{
Failer failer = new Failer();
object o = failer + new EventHandler(
delegate(object sender, EventArgs e)
{
// DO NOTHING
});
}
}
Sep 11 '08 #1
13 1191
On Thu, 11 Sep 2008 13:02:10 -0700, je**********@gmail.com
<je**********@gmail.comwrote:
Today I learned that the + operator cannot be passed a delegate. I get
an error from the CLR saying I have an invalid program.
Please provide a concise-but-complete code sample that reliably
demonstrates the problem. Also, please state exactly how you run the
program, exactly what error occurs, and how it's reported.

I'm not aware of any particular restriction along those lines, and I was
unable to reproduce the problem. Please see below for a
concise-but-complete code sample that demonstrates code that works fine on
my computer.

Pete

using System;

namespace TestDelegateAdditionOverload
{
class Program
{
class Test
{
public static Test operator +(Test test, MulticastDelegate del)
{
return test;
}
}

static void Main(string[] args)
{
Test test = new Test();

test = test + (EventHandler)delegate(object sender, EventArgs
e) { };

Console.WriteLine("done");
Console.ReadLine();
}
}
}
Sep 11 '08 #2
Of course It will work if you change my code. Go back to what I sent
and it will fail.
Sep 11 '08 #3
On Thu, 11 Sep 2008 14:22:44 -0700, je**********@gmail.com
<je**********@gmail.comwrote:
Of course It will work if you change my code. Go back to what I sent
and it will fail.
I demonstrated a concise-but-complete code sample that overloads the +
operator with a MulticastDelegate argument. That was the only complaint
in your original post.

I don't see any material differences between the code you posted and mine,
except that mine can be compiled and run and yours can't. But even if
there are material differences that I've overlooked, your question as
stated has been refuted by my example (you obviously can overload the +
operator with a MulticastDelegate argument), and you should not expect
people to bother compiling your code when you haven't provided a complete,
compilable code sample.

Pete
Sep 11 '08 #4
je**********@gmail.com wrote:
Today I learned that the + operator cannot be passed a delegate. I get
an error from the CLR saying I have an invalid program.
Congratulations, you've discovered a bug! Step right up to Microsoft Connect
to earn your prize...
With that, I was wondering if someone could tell me what other types I
am not allowed to make parameters.
It's not that, the compiler is emitting invalid IL, and the CLR barfs when
it encounters it.
class Failer
{
public static Failer operator +(Failer failer,
MulticastDelegate handler)
{
return failer;
}

public static void Test()
{
Failer failer = new Failer();
object o = failer + new EventHandler(
delegate(object sender, EventArgs e)
{
// DO NOTHING
});
}
}
Change this to

object o = failer + delegate...

That is, simply omit the explicit instantiation, and it will work. It will
also work if you use a method rather than an anonymous delegate. Your
original code is failing because it compiles to something like this:

..method public hidebysig static void Test() cil managed
{
// Code size 15 (0xf)
.maxstack 1
.locals init ([0] class ConsoleApplication2.Failer failer,
[1] object o)
IL_0000: nop
IL_0001: newobj instance void ConsoleApplication2.Failer::.ctor()
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: call class ConsoleApplication2.Failer
ConsoleApplication2.Failer::op_Addition(class ConsoleApplication2.Failer,

class [mscorlib]System.EventHandler)
IL_000d: stloc.1
IL_000e: ret
} // end of method Failer::Test

The call at IL_0008 is invalid because there's only one argument on the
stack as opposed to the two which are required. There's something going
wrong here with the magic the compiler uses to create event handlers from
delegates -- the required code is completely missing!

The corrected code looks like this:

..method public hidebysig static void Test() cil managed
{
// Code size 46 (0x2e)
.maxstack 4
.locals init ([0] class ConsoleApplication2.Failer failer,
[1] object o)
IL_0000: nop
IL_0001: newobj instance void ConsoleApplication2.Failer::.ctor()
IL_0006: stloc.0
IL_0007: ldloc.0
IL_0008: ldsfld class [mscorlib]System.EventHandler
ConsoleApplication2.Failer::'CS$<>9__CachedAnonymo usMethodDelegate1'
IL_000d: brtrue.s IL_0022
IL_000f: ldnull
IL_0010: ldftn void ConsoleApplication2.Failer::'<Test>b__0'(object,
class
[mscorlib]System.EventArgs)
IL_0016: newobj instance void
[mscorlib]System.EventHandler::.ctor(object,

native int)
IL_001b: stsfld class [mscorlib]System.EventHandler
ConsoleApplication2.Failer::'CS$<>9__CachedAnonymo usMethodDelegate1'
IL_0020: br.s IL_0022
IL_0022: ldsfld class [mscorlib]System.EventHandler
ConsoleApplication2.Failer::'CS$<>9__CachedAnonymo usMethodDelegate1'
IL_0027: call class ConsoleApplication2.Failer
ConsoleApplication2.Failer::op_Addition(class ConsoleApplication2.Failer,

class [mscorlib]System.EventHandler)
IL_002c: stloc.1
IL_002d: ret
} // end of method Failer::Test

You see the boilerplate here between IL_0008 and IL_0022 for creating your
event handler and loading it from a static field.

--
J.
Sep 11 '08 #5
Good analysis - one point, though:

"Change this to object o = failer + delegate..."

With the code as originally presented (MulticastDelegate), you'd need
to type the delegate:

o = failer + (EventHandler) delegate {...};

Of course, a better option would be to declare something more specific
for the "del" argument - perhaps using the Action<...or Func<...>
family to clarify the intent (EventHandler is fine too...).

Marc
Sep 12 '08 #6
Marc Gravell wrote:
Good analysis - one point, though:

"Change this to object o = failer + delegate..."

With the code as originally presented (MulticastDelegate), you'd need
to type the delegate:

o = failer + (EventHandler) delegate {...};
Oops, you're right, of course. Changing around things a little too
enthusiastically to pin down the root cause.
Of course, a better option would be to declare something more specific
for the "del" argument - perhaps using the Action<...or Func<...>
family to clarify the intent (EventHandler is fine too...).
Yes, using MulticastDelegate is pretty fishy -- I can't remember a single
occasion where I had a need to explicitly declare that.

--
J.
Sep 12 '08 #7
On Sep 11, 11:01*pm, Jeroen Mostert <jmost...@xs4all.nlwrote:
Marc Gravell wrote:
Good analysis - one point, though:
"Change this to object o = failer + delegate..."
With the code as originally presented (MulticastDelegate), you'd need
to type the delegate:
o = failer + (EventHandler) delegate {...};

Oops, you're right, of course. Changing around things a little too
enthusiastically to pin down the root cause.
Of course, a better option would be to declare something more specific
for the "del" argument - perhaps using the Action<...or Func<...>
family to clarify the intent (EventHandler is fine too...).

Yes, using MulticastDelegate is pretty fishy -- I can't remember a single
occasion where I had a need to explicitly declare that.

--
J.
Thank you. Someone who actually looks at the code I posted, instead of
just bashing me. It is nice to know that some people try to help
rather than always question the questions.
Sep 12 '08 #8
On Sep 11, 3:28*pm, "Peter Duniho" <NpOeStPe...@nnowslpianmk.com>
wrote:
On Thu, 11 Sep 2008 14:22:44 -0700, jehugalea...@gmail.com *

<jehugalea...@gmail.comwrote:
Of course It will work if you change my code. Go back to what I sent
and it will fail.

I demonstrated a concise-but-complete code sample that overloads the + *
operator with a MulticastDelegate argument. *That was the only complaint *
in your original post.

I don't see any material differences between the code you posted and mine, *
except that mine can be compiled and run and yours can't. *But even if *
there are material differences that I've overlooked, your question as *
stated has been refuted by my example (you obviously can overload the + *
operator with a MulticastDelegate argument), and you should not expect *
people to bother compiling your code when you haven't provided a complete, *
compilable code sample.

Pete
So, in other words, Pete, you don't know why my code doesn't run. The
fact of the matter is that I see your code and mine as somewhat
functionaly equivilent (aside from mine wrapping the anonymous method
inside of a delegate and yours simply using the anonymous method as
is).

For a typical programmer, the difference doesn't seem significant
enough to cause an InvalidProgramException. I was hoping someone could
explain why the difference would cause the error, regardless what my
original, uneducated post asked.

Thankfully, my real question was answered without being asked
directly. Some times asking the right question is harder than finding
the answer.
Sep 12 '08 #9
On Sep 12, 2:32*pm, "jehugalea...@gmail.com" <jehugalea...@gmail.com>
wrote:

<snip>
Thank you. Someone who actually looks at the code I posted, instead of
just bashing me. It is nice to know that some people try to help
rather than always question the questions.
It's not at all unreasonable to ask for code which is complete,
compiles, and demonstrates the problem. Yes, sometimes (as in this
case) it's possible for someone to modify the incomplete code when
it's presented such that it compiles and shows the described problem -
but it's *much* better to ask the question with code which compiles in
the first place. Being rude to someone who is trying to help (but
hasn't managed to reproduce your error) only serves to discourage
people from trying to help you in the future.

Jon
Sep 12 '08 #10
An interesting bug ;-p

If you do log it on connect, I'll happily click the "validated" button -
'tis definitely a compiler bug.

Marc
Sep 12 '08 #11
On Fri, 12 Sep 2008 06:44:56 -0700, je**********@gmail.com
<je**********@gmail.comwrote:
So, in other words, Pete, you don't know why my code doesn't run.
No, I don't. That's my point. If you don't post a complete code sample,
_no one_ can know why it doesn't run, unless they put extra effort in to
try to add enough code to get your code to run. Once they've done that,
they've necessarily got code that's different from yours, and there's no
guarantee that even if they can then reproduce a problem, it's the same
problem you see.

Since you didn't post a complete code sample, I had the option of either
trying to wrestle with your code to figure out exactly what you meant, or
to simply write my own code based on the text of your question. If all
goes well, the time commitment in either scenario is similar, but if not,
I could easily wind up spending more time with your code than just writing
it myself as I'd write it and still not come up with an answer.

It's an obvious choice: write the code oneself, and answer the question
that was asked. It's not my fault that your question made a false
assumption about the behavior you were seeing, and I don't see why you
seem to be taking me to task for answering the question you asked, rather
than the question you wish you'd asked.
[...]
Thankfully, my real question was answered without being asked
directly. Some times asking the right question is harder than finding
the answer.
Yes, you were fortunate that Jeroen was nice enough to do the extra work
you should have done yourself by converting your code sample into
something that could actually compile. You were also fortunate that
having done so, he was able to reproduce the same problem you found. You
should indeed be thankful.

The fact is, if a person asking a question cannot be bothered to do the
basic legwork to prepare a correct, complete question, that person should
have no expectation that anyone else will do that work for them. It's
great when it happens, but for you to have the attitude that anyone
responding to your question _must_ do that is arrogant.

You were lucky in this case, but it's worthwhile for you understand what
the problem here is with your post and especially your follow-ups. You
won't always be so lucky to have someone else willing to do your work for
you in the future and it will be good for you to understand the difference
between a complete code sample and an incomplete one.

Pete
Sep 12 '08 #12
On Fri, 12 Sep 2008 06:32:58 -0700, je**********@gmail.com
<je**********@gmail.comwrote:
Thank you. Someone who actually looks at the code I posted, instead of
just bashing me. It is nice to know that some people try to help
rather than always question the questions.
No one, least of all me, was "bashing" you. I made simple, reasonable
comments.

See my other reply for details. Your attitude is in the wrong place.
Sep 12 '08 #13
Peter Duniho wrote:
On Fri, 12 Sep 2008 06:44:56 -0700, je**********@gmail.com
<je**********@gmail.comwrote:
>[...]
Thankfully, my real question was answered without being asked
directly. Some times asking the right question is harder than finding
the answer.

Yes, you were fortunate that Jeroen was nice enough to do the extra work
you should have done yourself by converting your code sample into
something that could actually compile. You were also fortunate that
having done so, he was able to reproduce the same problem you found.
I'd like to point out that the only reason I did this was because an
InvalidProgramException always indicates a compiler bug (the compiler should
never produce a program that causes this)! If your problem had been less
interesting, I might not have bothered. Ditto if I wouldn't have been able
to reproduce it.

The fact that my analysis helped you should be considered a side effect -- I
wasn't actually helping you so much as satisfying my own curiosity.

Just to put things in perspective as to who was putting in effort to what end...

--
J.
Sep 12 '08 #14

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

17
by: Terje Slettebų | last post by:
To round off my trilogy of "why"'s about PHP... :) If this subject have been discussed before, I'd appreciate a pointer to it. I again haven't found it in a search of the PHP groups. The PHP...
3
by: A | last post by:
Hi, I understand that operator loading is used to support user-defined types. One of the requirements is that one of the arguments in an operator overloaded function must be of a user defined...
2
by: Bo Sun | last post by:
hi: in the following code: class plus{ int data_item; public:
6
by: woosu | last post by:
Hello ladies and gentlemen. I have a relatively simple problem that I've been unable to solve. In the interest of learning C++, I've decided to write a simple game. The basis for the game is...
51
by: Jojo | last post by:
Is there any way to get to the left-hand side of an operator? Consider the following (this is not meant to be perfect code, just an example of the problem): class Matrix { public: int data;...
18
by: uday | last post by:
Does C supports overloading. I am thinking no. But some people are saying yes. If yes how. Please answer with examples. Also in c++ size of empty class is one. why. and what are the default...
102
by: sam_cit | last post by:
Hi everyone, I have been asked this question quite a few times and i wonder what could the actual reason? " When to prefer C over C++ or vice versa, of course this is for real world pratical...
22
by: clicwar | last post by:
A simple program with operator overloading and copy constructor: #include <iostream> #include <string> using namespace std; class Vector { private: float x,y; public: Vector(float u, float...
9
by: Faisal | last post by:
Hi, Why C++ doesn't allow overloading of size of operator. I think it would be much handy to check the type userdefined types. For eg. In my project, I've some structures which contains...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.