|
Then someone start using your code, and spend whole day finiding empty catch buried under tons of code. Been there, cursed a lot.
"Throughout human history, we have been dependent on machines to survive. Fate, it seems, is not without a sense of irony. " - Morpheus
"Real men use mspaint for writing code and notepad for designing graphics." - Anna-Jayne Metcalfe
|
|
|
|
|
agreed. If you actually have to eat an exception, make your catch as narrow as possible to let any other exceptions flow up to error reporting systems. You can use string matching off the messagetext to narrow things down even if the base exception is being thrown instead of something more focused.
--
You have to explain to them [VB coders] what you mean by "typed". their first response is likely to be something like, "Of course my code is typed. Do you think i magically project it onto the screen with the power of my mind?" --- John Simmons / outlaw programmer
|
|
|
|
|
dan neely wrote: If you actually have to eat an exception, make your catch as narrow as possible to let any other exceptions flow up to error reporting systems.
I agree Dan. I've been bitten by bugs swallowed by empty catch blocks that catch Exception. A real pain to debug.
Kevin
|
|
|
|
|
Then put the MessageBox.Show(ex.ToString()); inside conditional code (does VB not have that?).
catch ( System.Exception ex )
{
# if DEBUG
MessageBox.Show(ex.ToString());
# endif
}
|
|
|
|
|
Yes, it does. The problem is that just eating exceptions willy-nilly is horrifyingly bad practice. It makes someone comming up behind you to maintain your code want to hunt you down and kill you!
|
|
|
|
|
Doing anything willy-nilly tends to lead to problems.
All decisions require thought and review.
|
|
|
|
|
There might be some scenarios, e.g., retrying. But in that case I would try and narrow down the exception type to an "expected" exception. If you just catch Exception how do you know that you're not swallowing a bug?
Kevin
|
|
|
|
|
Nasty. I've run into problems with these when maintaining code.
Kevin
|
|
|
|
|
Yeah, and try something like this:
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
try
{
int zero = 0;
int one = 1;
int exception = one / zero;
}
catch
{
throw new InvalidOperationException();
}
}
Let's say the exception is done by a third part plugin, so you can't control it.
Want you try to catch it in the Application.ThreadException event?
Ok, try it!
Not all scenarios allow you to fill the catch block.
|
|
|
|
|
I used to include this function in some classic VB apps:
Function RunningInDevEnv() as Boolean
On Error Resume Next
Debug.Print 1/0
RunningInDevEnv = (Err.Number <> 0)
End Function
I was curious and tried running this in VB.NET:
Function RunningInDevEnv() As Boolean
On Error Resume Next
Debug.Print(1 / 0)
Return (Err.Number <> 0)
End Function
It compiles in VB.NET but always returns True.
I noticed the C# compiler does not accept 1 / 0 at all. Is the VB.NET compiler being so forgiving here a good thing?
Sad to say some poor soul as I write this is probably trying to port one of my old VB apps to VB.NET and wondering why some "weird" behavior by the classic app in development mode is not carrying over to VB.NET. I hope the gods above will forgive me.
I think the lesson is to try to avoid clever tricks like this, even when they work (for awhile).
|
|
|
|
|
Follow the white rabbit...
VB6 wouldn't compile Debug.Print statements into the final code, and therefore wouldn't compile in the expression being evaluated either. Therefore if you were in the environment the division by zero would cause an error to be raised but you'd resume at the next statement, and the error number would be set to something other than 0, but in the compiled code the line causing the error wouldn't be present, so the problem wouldn't occur.
A debug build of the VB.NET code would cause the error to occur and the operation would return True. A release build should not. See the documentation for ConditionalAttribute .
The C# compiler tends to have better diagnostics and won't allow you to compile division by a literal zero. You'd have to use a variable containing the value 0.
|
|
|
|
|
.net already has the method. system.diagnostics.debugger.isattached
|
|
|
|
|
try creating a usercontrol, and put that control on a form. that method isnt very reliable as you will see.
|
|
|
|
|
A colleague of me retired and his code should be supported. Its old C code from an embedded system that has been ported from assembly.
BYTE Scan1, Scan2, Scan3, Scan4;
...
Err = ScanFunction(&Scan1);
That doesn't seems to be so bad, until i saw the Function declaration
int ScanFunction(unsigned long* pScan);
Later the data from the Scan bytes where placed in a long to work with the correct long value.
To be sure it would work even after changes a comment has been placed before the byte declaration
<br />
BYTE Scan1, Scan2, Scan3, Scan4
codito ergo sum
|
|
|
|
|
Makes perfect since to me! (Old C programmer)
I never liked tricks like that, but they do work in C. I would never recommend doing it though, as there are other ways to accomplish the same task. The only reason, I can think of, for ever doing something like this would be to reduce code, because you were limited by available memory. I have seen cases where adding any new code would have variables stepping on each other.
Ok
|--->...<---|
Opps!
|---->...|
|...<----|
INTP
"Program testing can be used to show the presence of bugs, but never to show their absence."Edsger Dijkstra
|
|
|
|
|
hmm. that's strange.
i've always seen it done like this:
BYTE Scan[4];
ulong *v = (ulong *)&Scan[0];
...
Err = ScanFunction(v);
much safer.
|
|
|
|
|
That may end up in a crash-boom-bang on hardware architectures which do not allow accessing words overlapping word boundaries. You'd have to use a union or #pragma (or something similar) to force alignment on the byte array.
|
|
|
|
|
Joergen Sigvardsson wrote: on hardware architectures which do not allow accessing words overlapping word boundaries
yeah like i got the time to worry about writing architecture-agnostic code
Windows on Intel is my target.
|
|
|
|
|
Yeah, but the other guy might be on some other platform.
(And no, I couldn't care less about other platforms either, as the stuff I write here will never run on anything but Wintel)
|
|
|
|
|
Would be better to encapsulate those 4 bytes in a struct
|
|
|
|
|
I'd do it like this:
union Data
{
unsigned long longVal;
BYTE asBytes[4];
};
Data d;
Err = ScanFunction(&d.longVal);
Steve
|
|
|
|
|
I had a similiar situation occur, albeit in Fortran; a variable was declared as a byte, but received as a long...
Took me a while to find out what was overwriting my data in the calling routine. The overwritten data was fixed values that shouldn't change!
Tim
|
|
|
|
|
I would have done it in binary like so:
1101010101001101110010100111010101010011011100101001
1010101010011011100101001110101010100110111001010010
0101010100110111001010011101010101001101110010100110
1101010101001101110010100111010101010011011100100101
1101010101001101110010100111010101010011011100101001
That way there's less confusion
There are 10 types of people in the world, those who understand binary and those who dont.
|
|
|
|
|
Someone just gave a database example on the forum using select * and I needed to drop in here and do a brief rant. I realize it was just an example and was unrelated to what they were showing, but still... I just got through fixing an application where this caused problems. I needed to make a small change to the application which required me to to add a few database columns. I added the columns in between related columns in the table. This of coarse broke everything because in addition to select * they also used datareader.getstring(0) ect. for the 60+ fields returned from the table. My additions put the columns in a new order when retrieved with select *.
Of course this wasn't the only problem... the whole thing was a nightmare. MS access backend, which of course means tons of bad inline sql (not paramitized). One big God class that handled everything and no database layer. Every small change I made broke 5 unrelated things. I ended up refactoring the whole thing. I pulled out related functionality into static helper classes, bad coding practice I know, but there wasn't time for proper class design. But I did implement some interfaces and decoupled significant sections of the code so that I could make changes without breaking everything.
Any way that's my coding horror rant... thanks I feel better.
topcoderjax - Remember, Google is your friend.
|
|
|
|
|
Ohhhhh, so it's your fault.
|
|
|
|