|
I'm afraid you missed a subtle point in my example, the point that gets you into your function with a NULL value. I've simplified it below
void Bar(CObArray &ar)
{
int foo = ar.GetCount();
}
void Foo(void)
{
CObArray *bob = NULL;
Bar(*bob);
} set a breakpoint on the "int foo = ar.GetCount()" and observe that ar cannot be examined in the debugger, it's value is null. Note that you do in fact get to that statement, that is, the "Bar(*bob)" in the function "Foo" does not throw an exception. Although it looks like it is dereferencing the clearly null pointer, it's really just creating the argument for Bar by getting the address of the CObject and passing it, that is, making a "by reference" value for the Bar function. Therefore, the "crash" happens in "Bar" (i.e. your function) rather than at the invocation site.
In my first reply, I was showing that the "ToBeAdded" object, which was valid, had a "Members" data member that was, in fact, NULL and that there was no "help" from the compiler / language rules that prevented it from passing NULL, even though the rules appear to say that's illegal.
So, my conclusion was that if you don't want to allow NULL as an input to your functions and that you used to explicitly ASSERT / check for that case, you need to continue to check for that case because simply using "&" to eliminate that possibility was not going to work.
Thus ends my rebuttal
|
|
|
|
|
What you describe is Microsoft (implementation) specific version of "undefined behavior". The code in Foo is ill-formed and any assumptions about what happens after you took a reference to a "null" pointer are worthless...(the lang. spec. does not require an exception to be thrown.)
|
|
|
|
|
Well, that is true to some extent (the undefined behavior part, not the malformed part )
Unfortunately, I don't live in the happy world where I can rely on everybody following the rules or where I can hold up a standard and claim it's not my fault that my code blew up.
I live in a world, somewhat dominated by Microsoft whose implementation details have real effects, where my libraries, reusable modules, etc are to be used by other programmers and they will often have bugs. I try my best to prevent their bugs from crashing my code but instead give them a reasonable exception or other error indicator so they can find their own bugs without calling me to say "your code crashed".
Perhaps this is ingrained in me from my early years of operating system development where a kernel crash was the worst possible thing regardless of what the "user" did to it via the APIs. Imagine how angry people would get if simple calls to the base Windows APIs would cause blue screens all the time.
paul_71 wrote: any assumptions about what happens after you took a reference to a "null" pointer are worthless
And this is exactly my point to the OP, his assumption that one cannot get into his code with a null object reference by using "&" is also worthless (your words) as I can clearly demonstrate that you can.
In any event, I will continue to challenge the assertion that one can remove defensive code because "by definition it cannot happen".
|
|
|
|
|
PS, it seems they've been arguing about this exact syntax for quite some time now. it appears there are two camps in the standard, one that wants it be defined behavior and one that does. The following like should provide some interesting reading on the subject.
http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#232
|
|
|
|
|
Ouch. I stand corrected. I started the day sure the sky was blue and now I'm left wondering if their implemetation ignores the statement "must be initialized by a valid object" and the part on page 198, section 8.5.3...
"...Argument passing (5.2.2) and function value return (6.6.3) are initializations."
But I agree (this includes some of your statements in another path of this thread as well), that I'm stuck with their implementation. I noticed they even let me dot off the invalid reference and call methods without any exceptions. At first I was shocked, but now I'm quite intrigued to see if any compiler vendor can implement this correctly.
I'm glad I never had to go up against you in debate class.
Excuse me while I go fix a million lines of active code.
|
|
|
|
|
Hm, not sure to whom this may concern, I always get confused by these hierarchies of threads... Anyway, the concept of a C++ reference is a subtle thing and it got even subtler with c++0x, as you might know. For good reasons this concept wasn't considered is what C# and other CLR targeting languages - and now we're back at OP's problem (at least as I see it...): in case of reference types (and in a verifiable program), you always deal with handles ("pointers") to instances. These handles can have two states: (a) pointing to valid object, (b) or "null". You can take a value of a "handle" by reference, by stating this intent explicitely at both call and target sites. However, this does not change the semantics of a handle, you just get access to the location of whatever the handle represents. So in C#, if you want to protect against handle pointing to "null", you either have to be explicit about that (code contracts are a great way to do that), or you rely on NullArgumentException handling (which is guaranteed to be thrown by the specs). The ref modifier mentioned somewhere in the thread does not help much:
void Bar(MyClass pParam) {
pParam.Member();
}
void Bar(ref MyClass pParam) {
pParam.Member();
pParam = new MyClass();
}
void Foo() {
MyClass tI1;
MyClass tI2 = null;
MyClass tI3 = new MyClass();
Bar(ref tI1);
Bar(ref tI2);
Bar(ref tI3);
Bar(tI1);
Bar(tI2);
Bar(tI3);
}
|
|
|
|
|
bob16972 wrote: If the caller violates the standard definition of a reference, there is nothing I can do about it. I'm not even sure there is a way to check the reference for validity since the result of the action you described would be undefined (or at least, so it seems).
Exactly, with no need to further qualify the statement as you did in the second sentence. And no, there is no way to check a reference for validity, since it must be valid by definition. Otherwise, the caller has violated (a) the language specification of a valid C++ program and (b) the contract you have specified by defining the method signature that way... That's what I wrote in my post above (which was down-voted for some reason).
|
|
|
|
|
Jeez. You missed the whole point of what I'm trying to do. You keep focusing on C++ references and pointers whereas I have no problem with C++ since I can choose to use pointers when I want to allow null and a reference when I don't. In C# sharp, I don't seem to have that option (except for ref apparently which would require a const to (attempt to) protect the caller from the method changing the reference on them.
From reading your earlier post, you apparently didn't read the code comments in my code examples as I had already stated that a reference can't be null but you tried to explain that very thing to me which would indicate you missed the point and the question.
Regardless, I appreciate your attempt to help find a solution, for what it's worth.
thanks.
|
|
|
|
|
Hello, I have a winform project in C# which I added a reference to windows media player.
when Im in the project properties I get the error:
An error occurred trying to load the page.
Error HRESULT E_FAIL has been returned from a call to a COM component.
Why is that?
The project is working fine including the player.
--Edit--
I found this error also but I didn't understand its meaning:
COM Reference 'WMPLib' is the interop assembly for ActiveX control 'AxWMPLib' but was marked to be linked by the compiler with the /link flag. This COM reference will be treated as a reference and will not be linked.
modified on Friday, January 14, 2011 2:30 PM
|
|
|
|
|
Hi,
Our solution in .net 3.5 has a number of dll's as output. In those dll's we populate some fields like version, company, product etc. But also a copyright notice. For instance, if I have this notice: "Copyright (c) 2011 Initech Inc.".
Is it possible to make the year value be determined at compile time? So, if I compile it in 2011, then it says "Copyright (c) 2011 Initech Inc.". If I compile it in 2012, it would say "Copyright (c) 2012 Initech Inc.".
I've toyed with some things, but AssemblyCopyright requires a constant as value.
Is it possible at all?
The consumer isn't a moron; she is your wife.
|
|
|
|
|
This always works for me
Hope it helps.
StreamReader reader = new StreamReader(@"C:\FilePath\AssemblyInfo.cs");
string contents = reader.ReadToEnd();
reader.Close();
string NewCopyrightText = "Yippie. All rights reserved " + DateTime.Now.Year;
string replacement = "[assembly: AssemblyCompany(\"" + NewCopyrightText + "\")]";
contents = Regex.Replace(contents, @"\[assembly: AssemblyCompany\("".*""\)\]", replacement);
StreamWriter writer = new StreamWriter(@"C:\FilePath\AssemblyInfo.cs", false);
writer.Write(contents);
writer.Close();
|
|
|
|
|
Thanks for the suggestion, but I was looking for a method of accomplishing this without the overwrite of AssemblyInfo.cs.
The consumer isn't a moron; she is your wife.
|
|
|
|
|
|
|
Exactly, you only need the word. You use the symbol when there isn't enough room for the word.
|
|
|
|
|
How can I run a program from inside my own.
by delphi I can do it by putting WinExec command
in my source code. what is the equivalent command in
sweet Language of C#? tnx
|
|
|
|
|
|
There is a thing called "the documentation", it holds answers to such elementary questions. Look for the Process class.
Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
|
|
|
|
|
I know there are many things to reffer. but cant u
answer a little more explicit? thanks anyway.
|
|
|
|
|
He did. It's your job as a programmer to understand the classes you're using. Read the documentation on the Process class and you'll probably end up learning a lot about the Process class instead of knowing just the single little use case that someone gives you in a code sample.
|
|
|
|
|
|
Hi,
I have to write an application that has the ability to perform a system-restart, shutdown or user-logoff. So far, I have found two solutions to do it, which both work very well. I'd like to know which is the best way to do it, i.e. if there are any disadvantages to the one or the other way to do it. Which is the most professional way to deal with it?
Currently, I use the System.Management Namespace, whic looks like the most elegant way to do this to me:
ManagementBaseObject mboShutdown = null;
using (ManagementClass mcWin32 = new ManagementClass("Win32_OperatingSystem"))
{
mcWin32.Get();
mcWin32.Scope.Options.EnablePrivileges = true;
ManagementBaseObject ShutdownParams = mcWin32.GetMethodParameters("Win32Shutdown");
ShutdownParams["Flags"] = "1";
ShutdownParams["Reserved"] = "0";
foreach (ManagementObject manObj in mcWin32.GetInstances())
{
mboShutdown = manObj.InvokeMethod("Win32Shutdown", ShutdownParams, null);
}
ret = true;
}
On the other hand, I have found many users who load the appropriate system-DLLs, and perform the whole tsak "unmanaged", an call ExitWindowsEx from these DLLs. This works too, but I am wondering why people decide to do it this way, if there is a namespace available in .NET that actually does it, like in my example above.
Which way would you chose, and why?
|
|
|
|
|
I have used neither one. I think I once used something akin to "Process.Start("shutdown") .
Luc Pattyn [Forum Guidelines] [My Articles] Nil Volentibus Arduum
Please use <PRE> tags for code snippets, they preserve indentation, improve readability, and make me actually look at the code.
|
|
|
|
|
The un-managed code is not recommended one in long term, although it is faster way to achieve same.
With managed, good way is:
using System.Diagnostics;
ProcessStartInfo startinfo = new ProcessStartInfo("shutdown.exe","-r");
Process.Start(startinfo);
Keep in mind the options you want to use:
-i Display GUI interface, must be the first option
-l Log off (cannot be used with -m option)
-s Shutdown the computer
-r Shutdown and restart the computer
-a Abort a system shutdown
-m \\computername Remote computer to shutdown/restart/abort
-t xx Set timeout for shutdown to xx seconds
-c "comment" Shutdown comment (maximum of 127 characters)
-f Forces running applications to close without warning
-d [u][p]:xx:yy The reason code for the shutdown, u is the user code, p is a planned shutdown code, xx is the major reason code (positive integer less than 256)
,yy is the minor reason code (positive integer less than 65536)
|
|
|
|
|
RaviSant wrote: The un-managed code is not recommended one in long term
Got a citation for this??
|
|
|
|
|