|
Unfortunately, he didn't lose the unfortunate job.
|
|
|
|
|
It's bad practice to name something using the same name as a built in function, even if it does work.
|
|
|
|
|
The bad practice is failing to write the statement explicitly.
Why change MONTH when it's meant to be 'month'?
The shame is not using "SELECT B.[MONTH] + MONTH..."
Yet, even that is minor.
|
|
|
|
|
One of our legacy reporting applications written in VB6 and using Crystal Reports recently started experiencing random crashes on the customer end when opening reports. The problem never occured in the development environment, or in any of the test environments we use. As mentioned, crashes were random, and were happening regardless of the report. This is what I found in the General Declarations of the Reports form:
Dim app As CRAXDRT.Application
Why is this even possible?. I changed it to
Dim CRApp As CRAXDRT.Application
and replaced where needed...problem resolved. Anyone see how this might cause random crashes?
"Go forth into the source" - Neal Morse
|
|
|
|
|
Perhaps there was a global variable called "app" already, and declaring another "app" variable at form level was causing code in the form that was trying to reference the global variable to reference the local one instead?
Or maybe your app is just crap! :P
|
|
|
|
|
Well he did say it was using Crystal Reports already.
Chris Meech
I am Canadian. [heard in a local bar]
In theory there is no difference between theory and practice. In practice there is. [Yogi Berra]
posting about Crystal Reports here is like discussing gay marriage on a catholic church’s website.[Nishant Sivakumar]
|
|
|
|
|
Which I why I called it CRApp! Self-documenting code!
"Go forth into the source" - Neal Morse
|
|
|
|
|
kmoorevs wrote: Anyone see how this might cause random crashes?
No, certainly a variable name won't cause that.
|
|
|
|
|
You are correct. One of the affected customers is running a new version with the object renamed. Due to the randomness of it, it appeared to have solved the problem, however, the problem has resurfaced. I'm actually glad the variable/object name was not the culprit...it would've violated scope as I understand it. Luckily, in the last build, I put in a simple trace log so that I now know the method causing the fault. (I can see exactly where CRApp is CRApping out!) Still, there are some variable names (like app) that one should avoid.
"Go forth into the source" - Neal Morse
|
|
|
|
|
Did they try rebooting/reinstalling previous version first? Maybe the file was corrupted.
"You get that on the big jobs."
|
|
|
|
|
Tried that a long while back, but the problem persists...changing the variable name was not the answer. Starting to smell like dll hell, but even that puzzles me, since it seems so random. Anyway, I know this is the wrong forum for troubleshooting. Thanks
"Go forth into the source" - Neal Morse
|
|
|
|
|
Way, way back when I first started programming in VB6 (about eight years ago, haven't touched it since!) I seem to recall there was a global variable that VB6 defined as "App"
Examples: App.PrevInstance, App.Title, App.HelpFile
It's possible that, somewhere without even knowing it, your application was referring to a variable on the VB6 App object (which wouldn't exist in your redefinition of the app variable, remember VB6 is case insensitive).
Being a .NET developer today, the fact that your app was done in VB6 is one thing that clued me in on this issue: the global App variable does not exist in VB.NET.
|
|
|
|
|
Exactly! (and thanks for posting!) I was wondering how I could even declare app as a Crystal Report Application object to begin with. Turns out it works fine and was not the cause of our problems. The problem was corrected by using late binding on the Crystal App object.
"Go forth into the source" - Neal Morse
|
|
|
|
|
Inspired by the goto comments in the lounge today...
Msny years ago a co-worker showed me his first program after we had banned the use of goto statements at our company.
His program had a main loop like:
If var = 1 gosub 100
If var = 2 gosub 200
and so on..
and inside each subroutine before leaving, it would set var to whatever it needed to be next.
An abstracted goto !
This is back in the days before OO and events. This was procedural type code and in this case.. a goto would have been clearly easier to understand.
|
|
|
|
|
That's why I always get scared when such rules are preached religiously and then applied at all cost. I often write code for old 8 bit computers or microcontrollers and calling functions for everything will result in a slow processor working more on the stack than the actual task. Using goto or branching instructions in assembly then will make more of the two most valuable resources, CPU and memory. Thinking and making most of the resources at your disposal is more important than blindly following rules.
I'm invincible, I can't be vinced
|
|
|
|
|
Agreed.
I really don't understand the goto hate, although I've never worked in an environment where it was an issue. There are times when goto makes sense even in modern programming techniques.
|
|
|
|
|
I can understand it.
There are indeed times when goto makes sense. The problem is that it is taught to people who do not have the experience to understand when those times are, so use it when a "proper" alternative would be more work.
Blame the teachers! I do...
Ideological Purity is no substitute for being able to stick your thumb down a pipe to stop the water
|
|
|
|
|
Wish it was more obvious in tutorials. The impression I get is "Don't ever use goto ". That just made me wonder why switch/cases use the same syntax.
Anyone have a link to explain when it's a good idea?
|
|
|
|
|
No!
It's not a hard and fast rule - it depends on the complexity of what you are doing and why you might need it.
Sorry - but it's an experience thing, not something you can easily take down to a list of "if this and this and this, but not that or that, then..."
It's like driving a car - after a while you get a feel for "Is now a good time to pull out of this side turning?". It's not something you can easily explain.
Ideological Purity is no substitute for being able to stick your thumb down a pipe to stop the water
|
|
|
|
|
Not that I have used it, but the case some have made is breaking out of deeply nested loops (and not with exceptions):
for (i = 0; i < end; i++) {
doSomething();
for(j = obj[i].getAnotherObj(); j++; obj[i].end()) {
doSomethingElse();
for(k = anotherObj[j].getYetAnotherObj(); k++; anotherObj[j].end()) {
if (yetAnotherObj[k].condition())
goto breakOutOfDeeplyNestedLoop;
doYetSomethingElse();
}
blahBlah();
}
blahBlahBlah();
}
breakOutOfDeeplyNestedLoop:
moreStuffInThisMethod();
You could use exceptions, but that's really a misuse of them if the condition is not truly exceptional.
|
|
|
|
|
Ah yes, in some of my console apps I have a while loop for the console input, with continue to indicate that the command was recognised and bypass the rest of the commands in the loop.
Of course once I nested a for loop, I had to use a bool to ensure whether the loop should have used continue or not.
So assuming a similar scenario, instead of
while(settext())
{
if(!stricmp(text, "something"))
{
DoStuff();
continue; }
if(!strincmp(text, sizeof("other thing ")-1, "other thing "))
{
for(unsigned int i = 0; i < StringArray.size(); ++i)
{
if(!stricmp(text+sizeof("other thing ")-1, StringArray[i]))
{
StringArray.erase(i);
break; }
}
ReportError("parameter not found");
continue; }
if(!stricmp(text, "asparagus"))
{
continue; }
ReportError("command not found);
JumpHere:
continue; // Labels must have a statement
}
So that would be an applicable scenario?
modified 28-Feb-12 14:49pm.
|
|
|
|
|
Good example exactly of not using goto at all,
it's easily converted to an if then else situation.
which increases readability if u would ask me.
while(settext())
{
if(!stricmp(text, "something"))
{
DoStuff();
}
else if(!strincmp(text, sizeof("other thing ")-1, "other thing "))
{
for(unsigned int i = 0; i < StringArray.size(); ++i)
{
if(!stricmp(text+sizeof("other thing ")-1, StringArray[i]))
{
StringArray.erase(i);
break;
}
}
ReportError("parameter not found");
}
else if(!stricmp(text, "asparagus"))
{
}
else
{
ReportError("command not found");
}
}
|
|
|
|
|
I believe you read that wrong, please read the comments I have in the code. The point here was exiting out of the the for loop embedded in the while loop, not the if format
Although I am also interested if using if -else -if actually is faster than repetitive
if() {code(); end_if_checks();} if() {...} in my example though.
|
|
|
|
|
If u want speed, i would const the size of for your fixed string,
would safe u getting it's length each time u go for another loop in the while.
The continues u fire are at end of each if slice, and in an if else construction
it would jump out to bottom anyways, so in this case i think continue actually will be equally fast at best and else even slower.
for(unsigned int i = 0; i < StringArray.size(); ++i)
{
if(!stricmp(text+sizeof("other thing ")-1, StringArray[i]))
{
StringArray.erase(i);
break;
}
}
I normally do different, a bit slower i assume but clear
const int Sizer = sizeof("other thing ")-1;
int WalkTo = StringArray.size() - 1;
if (WalkTo >= 0)
{
const char* Check = text + Sizer;
int i = -1;
int Found = 0;
do
{
i++;
if (!stricmp(Check, StringArray[i]))
{
StringArray.erase(i);
Found = 1;
}
} while (!Found && (i < WalkTo));
}
modified 29-Feb-12 3:31am.
|
|
|
|
|
Okay, let me add a line at the prefix to clear up any confusion:
std::vector<std::string> StringArray;
The StringArray.size() gets the size of an array of std::strings, not an array of chars.
Say the StringArray was initialised to a set of usernames, in a server for example, and the command 2 could be "disconnect xxx".
|
|
|
|