As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
Many months back, I had to fix up some code that caused some problems. The code looked basically like this:
int badFun() { return badFun(); }
This obviously caused a stack overflow even in the high level language I was working with (4Test in SilkTest). There's no way this code could be seen as beneficial. The first sign of problems were warnings seen after the script finished, but no compile errors or warnings. Curiously, I tried writing programs in C++, C# and Python with the same structure, and all of them compiled/interpreted with no syntax errors or warnings, even through there were runtime errors in all cases. I didn't even see any warnings in any of these cases. Why isn't this seen as a possible problem by default?
EDIT: I tried writing the equivalent of that function in all three languages, so I added those function tags. I'm more interested in overall reasons why code like this gets through with no warnings. Please retag if necessary.
Here's the deal: compiler warnings are features. Features require effort, and effort is a finite quantity. (It might be measured in dollars or it might be measured in the number of hours someone is willing to give to an open source project, but I assure you, it is finite.)
Therefore we have to budget that effort. Every hour we spend designing, implementing, testing and debugging a feature is an hour we could have spent doing something else. Therefore we are very careful about deciding what features to add.
That's true of all features. Warnings have special additional concerns. A warning has to be about code that has the following characteristics:
Legal. Obviously the code has to be legal; if it is not legal then its not a warning in the first place, its an error.
Almost certainly wrong. A warning that warns you about correct, desirable code is a bad warning. (Also, if the code is correct, there should be a way to write the code such that the warning goes away.)
Inobvious. Warnings should tell you about mistakes that are subtle, rather than obvious.
Amenable to analysis. Some warnings are simply impossible; a warning that requires the compiler to solve The Halting Problem for example, is not going to happen since that is impossible.
Unlikely to be caught by other forms of testing.
In your specific example, we see that some of these conditions are met. The code is legal, and almost certainly wrong. But is it inobvious? Someone can easily look at the code and see that it is an infinite recursion; the warning does not help much. Is it amenable to analysis? The trivial example you give is, but the general problem of finding unbounded recursions is equivalent to solving the halting problem. Is it unlikely to be caught by other forms of testing? No. The moment you run that code in your test case, you're going to get an exception telling you precisely what is wrong.
Thus, it is not worth our while to make that warning. There are better ways we could be spending that budget.
Why isn't this seen as problem by default?
The error is a run time error, not a compile time error. The code is perfectly valid, it just does something stupid. The very simple case that you show could certainly be detected, but many cases that would be only slightly more complicated would be difficult to detect:
void evil() {
if (somethingThatTurnsOutToAlwaysBeTrue)
evil();
}
In order to determine whether that's a problem, the compiler has to try to figure out whether the condition will always be true or not. In the general case, I don't think this is any more computable than determining whether the program will eventually stop (i.e. it's provably not computable).
No compiler of any programming language has any sort of idea about the semantics of the code it compiles. This is valid code, though stupid, so it will be compiled.
How is the compiler or interpreter suppose to know what the function is doing? The scope of the compiler and interpreter is to compile or interpret the syntactical code-- not interpret the semantics of your code.
Even if a compiler did check for this, where do you draw the line? What if you had a recursive function that calculated factorial forever?
Because compiler will not check for these kind of stuff.
If you install a code analyzer like Resharper in Visual Studio it bring a warning of infinite recursive call or sth like that in case you enabled the code analysis option.
I doubt the compiler can detect a run-time phenomena (stack overflow) at compile time. There is many valid cases to call a function inside itself, recursion. But how can the compiler know the good from the bad cases of recursion?
Unless it has some added AI to it, I don't think a compiler could detect the differences between good and bad recursion, that's the job of a programmer.
As you have mentioned Compiler just checks syntatical errors.
the recursive function isperfectly valid w/o any error.
During Runtime,
when stack is overflown it throws an error because of stack overflow *not because of code*.
Recursive function is perfetly valid, but again in implementation we need to put condition check to return values before stack is filled.
Related
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 2 years ago.
Improve this question
In C++, a function with a non-void return type without a return statement is allowed. So, the following code will compile:
std::string give_me_a_string()
{
}
In C#, however, such a method is not allowed. So, the following code will not compile:
public string GiveMeAString()
{
}
Why is this the case? What was the design rationale in these two languages?
C++ requires code to be "well-behaved" in order to be executed in a defined manner, but the language doesn't try to be smarter than the programmer – when a situation arises that could lead to undefined behaviour, the compiler is free to assume that such a situation can actually never happen at runtime, even though it cannot be proved via its static analysis.
Flowing off the end of a function is equivalent to a return with no value; this results in undefined behavior in a value-returning function.
Calling such a function is a legitimate action; only flowing off its end without providing a value is undefined. I'd say there are legitimate (and mostly legacy) reasons for permitting this, for example you might be calling a function that always throws an exception or performs longjmp (or does so conditionally but you know it always happens in this place, and [[noreturn]] only came in C++11).
This is a double-edged sword though, as while not having to provide a value in a situation you know cannot happen can be advantageous to further optimization of the code, you could also omit it by mistake, akin to reading from an uninitialized variable. There have been lots of mistakes like this in the past, so that's why modern compilers warn you about this, and sometimes also insert guards that make this somewhat manageable at runtime.
As an illustration, an overly optimizing compiler could assume that a function that never produces its return value actually never returns, and it could proceed with this reasoning up to the point of creating an empty main method instead of your code.
C#, on the other hand, has different design principles. It is meant to be compiled to intermediate code, not native code, and thus its definability rules must comply with the rules of the intermediate code. And CIL must be verifiable in order to be executed in some places, so a situation like flowing off the end of a function must be detected beforehand.
Another principle of C# is disallowing undefined behaviour in common cases. Since it is also younger than C++, it has the advantage of assuming computers are efficient enough to support more powerful static analysis than what the situation was during the beginning of C++. The compilers can afford detecting this situation, and since the CIL has to be verifiable, only two actions were viable: silently emit code that throws an exception (sort of assert false), or disallow this completely. Since C# also had the advantage of learning from C++'s lessons, the developers chose the latter option.
This still has its drawbacks – there are helper methods that are made to never return, and there is still no way to statically represent this in the language, so you have to use something like return default; after calling such methods, potentially confusing anyone who reads the code.
As it currently stands, this question is not a good fit for our Q&A format. We expect answers to be supported by facts, references, or expertise, but this question will likely solicit debate, arguments, polling, or extended discussion. If you feel that this question can be improved and possibly reopened, visit the help center for guidance.
Closed 11 years ago.
Here is an example of the type of article I'm talking about:
http://support.microsoft.com/kb/319401
I assume these articles are written by people who work for Microsoft and that the code in the articles will always be rock solid and never contain any malicious code. I just want to make sure I can explain to my boss that this is an ok place to copy code from (I've been told never to copy code from the internet, but this seems like a safe source).
I would trust them not to be malicious, but they're not always good code. (MSDN samples are sometimes pretty awful.)
For example, here's some code in the sample you gave:
compareResult = ObjectCompare.Compare
(listviewX.SubItems[ColumnToSort].Text,
listviewY.SubItems[ColumnToSort].Text);
// Calculate correct return value based on object comparison
if (OrderOfSort == SortOrder.Ascending)
{
// Ascending sort is selected, return normal result of compare operation
return compareResult;
}
else if (OrderOfSort == SortOrder.Descending)
{
// Descending sort is selected, return negative result of compare operation
return (-compareResult);
}
else
{
// Return '0' to indicate they are equal
return 0;
}
Now, there are two issues here:
Why is it deemed valid to have a comparer with no sort order? This should be a constructor parameter, validated at the point of construction IMO.
You should not just negate the result of one comparison to perform a "reverse comparison". That breaks if the result of the first comparison is int.MinValue - because -int.MinValue == int.MinValue. It's better to reverse the arguments used to perform the original comparison.
There are other things I'd take issue with in this code, but these two should be enough to make my point.
I heartily agree with the other answers too, in terms of:
- Check the copyright / licence etc of any code you want to use
- Make sure you understand anything you want to use
Your boss probably wouldn't mind if you only copied the code into a test project that you use to test and understand the code. You can then use what you've learned to write the production code.
And while I don't think anyone outside of Microsoft knows the names of the people who write those support articles, they come from the same vendor that your toolchain does, so if you don't trust the support articles, then you can't trust the tools you've bought either.
Microsoft Knowledgebase articles show safe (as in non-malicious but not necessarily secure) code, but usually the example provides the most basic use case possible. There's a good chance that you'll have to tweak the code a bit for it to work the way you want.
You should also pay attention to the date of the articles. For example, the article you link to is almost three years old. There's definitely a better way to handle that situation now.
Be aware that most codes in articles are there to help you understand the concepts. They are not "production ready". Learn the concepts instead and implement your own.
Have you been told not to copy code from the internet because of rights issues? If so then you don't have to worry about this Microsoft code.
I would advise you not to use any code you don't understand. If you can't say if the code is malicious or not don't use it.
MSDN and kb support articles are written by MS employees that are part of the given product's UX team (user experience). These are people who typically have a background in technical writing, but are not necessarily developers themselves (although some are). It's very common for the UX team to collaborate with developers on the product to ensure their code samples are correct. However this collaboration in my experience is one of the lowest priorities a typical MS developer has and can go ignored, and so it can at times lead to poor code getting out.
With that said, I completely agree with Carl Norum's comment. Copying code you do not understand is done at your own risk. Make sure you understand any code you place in your product!
I've always found the Microsoft articles to be of the highest quality (sadly not their products).
However, there's always the danger of a spoofing site.
Explain that you carefully read the article to understand the information in there, and only copy code that you understand.
If you don't understand the code, then even if the code is correct it may not be doing what you actually need done, thus your program will be incorrect.
You also will have a hard time debugging and maintaining code if there are parts that you don't understand.
Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 9 years ago.
Improve this question
I'm looking for a tool (paid or OSS) to convert a mid-sized VB.NET project to a C# project. I've searched StackOverflow and have found a few questions/answers, but most suggest .NET Reflector or online copy/paste single file tools. Reflector doesn't seem to fit the bill as it will convert an assembly, but we're looking for a whole-sale project converter which will maintain the project including file names, comments, etc.
We're fully willing to manually address items that cannot be automatically converted, but would like to start off with a fairly comprehensive converted project.
One recommendation we found is Elegance Technologies' CSharpener for VB.NET - http://www.elegancetech.com/csvb/csvb.aspx. Based on their site, it hasn't been revved since pre-VS 2008.
Recommendations will be appreciated.
SharpDevelop is an open source IDE and it allows you to covert between VB and C#.
Do be aware that there are some things which can be done nicely in VB.net that cannot be done nicely, if at all in C# (and vice versa). Two of note:
In vb.net, declaration-initializations (e.g. "Dim Foo As Bar = Whatever") in a derived class occur after the base constructor has run, and can make reference to the object being constructed. In C#, such declaration-initializations occur before the base constructor is run, and cannot reference the object under construction. One could probably move all such initialization to the constructor, but if there are multiple constructors that may require the creation of redundant code.
In vb.net, a Catch statement may include a condition (e.g. Catch Ex As FancyException When Ex.SomeProperty = 9). In C#, the only way to a achieve a somewhat similar result is to catch an exception and then decide if it meets the necessary criteria, rethrowing if not; this will yield different semantics in a number of ways. Among other things, at the time the When clause is evaluated, Finally statements which will be tripped by the exception will not yet have run, so allowing the state of the system to be captured. Further, if break-on-unhandled-exception is set, and no "When" condition is satisfied, the debugger will break at the location where the original exception occurred. If the exception had been caught and rethrown, the debugger would break at the re-throw.
I would think an IL-to-C# translator might do an okay job of moving initializations to an object's constructors, though that lead to some annoying repetition. I don't think there's any way for C# code to match the semantics of VB.net's exception handling, though.
Two words: A programmer.
If you want it to be the most bug free and just work hire a programmer.
A quick google turns up http://www.freelancer.com where you can hire a one time programmer.
If you're not satisfied with SharpDevelop, TangibleSolutions will provide support with their converters to ensure your happiness.
SharpDevelop is quite good, but at my company we've found VBConversions to provide a much more complete conversion. It's a commerical app though, but for the time saved over SharpDevelop it was a no-brainer for us.
As a specific example, one thing we found that SharpDevelop didn't convert correctly was VB indexes, which use curvy brackets. It seemed unable to distinguish between indexes and method calls so didn't convert the indexes to square brackets. VBConversions converted them fine. This one thing made it worth its purchase for us.
It's difficult to tell what is being asked here. This question is ambiguous, vague, incomplete, overly broad, or rhetorical and cannot be reasonably answered in its current form. For help clarifying this question so that it can be reopened, visit the help center.
Closed 12 years ago.
i'm writing an interesting program, and every performance hit is very painful for me.
so i'm wondering what is better - to make an extra "if" statement to reduce a number of function calls, or to avoid those "if" adn get more funciton calls. the function is virtual method, that overrides IEqualityComparer's method Equals, all it does is comparing the size and the hash of 2 files.
the if statement compares the size of these 2 files. i think you got the point of this logic.
as you can see i'm writing this program in C#. So maybe anyone can answer me, because this is not the first time i'm wondering what to choose. thanks
If you really need that much performance so badly, why don't you program in assembly language?
If you are still sure you absolutely need to worry about this, first check for other optimization opportunities that have more potential (a better algorithm can make orders of magnitude more differnece than any microoptimization).
If you optimized the living shit out of everything else, the only way to be sure is to profile. Really. No matter how hard anyone of us tries to guess, they will likely underestimate the JIT.
Still I have an opinion on this: Generally speaking, branch misprediction can hurt much more than a function call, since it screws the cache. But who says it compiled down to code that is likely to blow the cache? Edit: But since it seems like you're comparing file contents for strict equality, short-circuiting in case the length differs can save much time (Consider: how long does it take the filesystem to tell you the length? It likely already knows, so nearly none. How long does it take you to hash a 10 MB file? VERY long, n comparision). So if I guessed that correctly, then go for the short-circuiting, for crying out loud.
Have you tried profiling to find out? Are you sure that either of these is the bottleneck in your application?
Keep if - it will run much faster.
It is clear that creating hash of an file will take considerably more time than if.
In the old days, back in the 486 and older days, when CPUs were "dumb", branching logic (e.g. an if()) would cause a pipeline and/or cache flush, which would slow things down. These days, with modern compilers and out-of-order branch-predicting wash-your-dishses-for-you CPUs, such overhead is minimal.
The only proper way to answer your question is: benchmark both methods and see which is faster.
Is the pain caused by the actual performance you observe while testing or just by the fact that you think about possibility of wasting a few cycles? If it's the second case the only sane way to fix the problem is by working on attitude.
The cost of a branch is very hard to predict, because modern processors use some very clever techniques to speed the execution. They store some special data structures that are used to predict the branch target. The branch is very cheap if the prediction is correct and pretty costly otherwise. The rate of incorrect predictions is low, but of course not zero. I don't think You can get a definitive answer for your question
My guess would be that an if statement is better, but with today's advanced compilers you can never really tell. Your best bet is to try both and compare the performance.
It's really hard to know without profiling. But either way, I can tell you that your algorithms are generally going to be much more important than if vs function, and going with functions usually makes it easier to change out and update implementations much more easily, rapidly, and safely, allowing you ultimately to do more to improve the more important parts of your algorithms. And, again, the way to know how you're doing there is to profile.
The answer depends on one thing: "am I using a completely braindead compiler"
And since you're not, the answer is "it doesn't matter". The compiler and JIT'er heavily transforms your code, so what is actually executed looks nothing like the code you wrote.
For example, function calls can be inlined, eliminating all the overhead of the function call.
Therefore: write code that is easy to understand for yourself, and as a side bonus, it also becomes easier to understand for the compiler when it optimizes your code.
if can have a cost due to branching. The cost depends on the code run in the if case, the code run in the else case, the size of the CPU cache, and compiler decisions.
Function call can have a cost due to, well, to the cost of calling a function. This can be much bigger than for if or it can be zero (because the call was inlined - and inlining can even happen with virtual calls when the compiler could "see" which form was going to be called at compile time), or it can be in between.
Because of this, there really is no general answer to this question. Even if you profile, there is nothing to say that it won't be different on a different architecture even with a binary copy of the assembly (because the jitter will be different) or with a different version of the .NET environment (and here "different version" includes service packs, hot-fixes and patches that touch on it).
Closed. This question is off-topic. It is not currently accepting answers.
Want to improve this question? Update the question so it's on-topic for Stack Overflow.
Closed 10 years ago.
Improve this question
I couldn't find any question that directly applies to my query so I am posting this as a new question. If there is any existing discussion that may help me, please point it out and close the question.
Question:
I am going to do a presentation on C# coding guidelines but it is not supposed to limit to coding standards.
So I have a rough idea but I think I need to address good programing practices. So the contents will be something like this.
Basic coding standards - Casing, Formatting etc.
Good practices - Usage of Hashset over other data structures, String vs String Builder, String's immutability and using them effectively etc
Really I would like to add more good practices (Especially to improve the performance.) So like to hear some more good practices to be used with C#. Any suggestions??? (No need of large descriptions :) Just the idea is sufficient.)
Coding Guidelines for CSharp 3.0 and 4.0
IDesign Coding Standards
Lance Hunt's C# Coding Standards
Brad Abrams' Internal Coding Guidelines
Unsurprisingly, I just found a SO question: C# Coding standard / Best practices
Here are a few tips:
Use FxCop for static analysis.
Use StyleCop for coding style validation.
Because of the different semantics of value types, supply them with an alternative color in the IDE (go to Tools / Options / Environment / Fonts and Colors / Display Items and supply User Types (Enums) and User Types (Value types) with a value like #DF7120 [223, 113, 32]).
Because exceptions tend to show bugs in your code, let the IDE break on all exceptions. (go to Debug / Exceptions... / Common Language Runtime Exceptions and check Throw).
Project settings: Disallow unsafe code.
Project settings: Threat warnings as errors.
Project settings: Check for arithmetic overflow/underflow.
Use variables for a single, well defined goal.
Don't use magic numbers.
Write short methods. A method should only contain one level of abstraction.
A method can never be too small (a method of 20 lines is considered pretty big).
A method should protect itself against bad input.
Consider making a type immutable.
Don't suppress warnings in your code with pragma warning disable.
Don't comment bad code: rewrite it.
Document explicitly in code why you are swallowing an exception.
Note the performance implications of concatenating strings.
Never use goto statements.
Fail early, fail fast.
I'm using Microsoft's Design Guidelines for Developing Class Libraries.
And I think it is quite good to start with.
Basic Coding Standards - Make sure it's consistent. Even if they don't follow the conventions set out in this document on msdn. I think consistency is really key here.
Unit Tests - You cannot go wrong here.
Security - Talk about ensuring that if you are passing sensitive data around that it's secure.
Performance - You know, I personally feel that getting the application right and then looking at performance is what I do. I do have it in the back of my mind when writing code, so it's little fine tunings that come in at the end.