Code compiles and executes even when surrounded only by Braces [duplicate] - c#

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.
I mean other than using it when required for functions, classes, if, while, switch, try-catch.
I didn't know that it could be done like this until I saw this SO question.
In the above link, Eli mentioned that "They use it to fold up their code in logical sections that don't fall into a function, class, loop, etc. that would usually be folded up."
What other uses are there besides those mentioned?
Is it a good idea to use curly braces to limit the scope of your variables and expand the scope only if required (working on a "need-to-access" basis)? Or is it actually silly?
How about using scopes just so that you can use the same variable names in different scopes but in the same bigger scope? Or is it a better practise to reuse the same variable (if you want to use the same variable name) and save on deallocating and allocating (I think some compilers can optimise on this?)? Or is it better to use different variable names altogether?

I do if I am using a resource which I want to free at a specific time eg:
void myfunction()
{
{
// Open serial port
SerialPort port("COM1", 9600);
port.doTransfer(data);
} // Serial port gets closed here.
for(int i = 0; i < data.size(); i++)
doProcessData(data[i]);
etc...
}

I would not use curly braces for that purpose for a couple reasons.
If your particular function is big enough that you need to do various scoping tricks, perhaps break the function into smaller sub-functions.
Introducing braces for scoping to reuse variable names is only going to lead to confusion and trouble in code.
Just my 2 cents, but I have seen a lot of these types of things in other best practice materials.

C++:
Sometimes you need to introduce an extra brace level of scope to reuse variable names when it makes sense to do so:
switch (x) {
case 0:
int i = 0;
foo(i);
break;
case 1:
int i = 1;
bar(i);
break;
}
The code above doesn't compile. You need to make it:
switch (x) {
case 0:
{
int i = 0;
foo(i);
}
break;
case 1:
{
int i = 1;
bar(i);
}
break;
}

The most common "non-standard" use of scoping that I use regularly is to utilize a scoped mutex.
void MyClass::Somefun()
{
//do some stuff
{
// example imlementation that has a mutex passed into a lock object:
scopedMutex lockObject(m_mutex);
// protected code here
} // mutex is unlocked here
// more code here
}
This has many benefits, but the most important is that the lock will always be cleaned up, even if an exception is thrown in the protected code.

The most common use, as others have said, is to ensure that destructors run when you want them to. It's also handy for making platform-specific code a little clearer:
#if defined( UNIX )
if( some unix-specific condition )
#endif
{
// This code should always run on Windows but
// only if the above condition holds on unix
}
Code built for Windows doesn't see the if, only the braces. This is much clearer than:
#if defined( UNIX )
if( some unix-specific condition ) {
#endif
// This code should always run on Windows but
// only if the above condition holds on unix
#if defined( UNIX )
}
#endif

It can be a boon to code generators. Suppose you have an Embedded SQL (ESQL) compiler; it might want to convert an SQL statement into a block of code that needs local variables. By using a block, it can reuse fixed variable names over and over, rather than having to create all the variables with separate names. Granted, that's not too hard, but it is harder than necessary.

As others have said, this is fairly common in C++ due to the all-powerful RAII (resource acquisition is initialization) idiom/pattern.
For Java programmers (and maybe C#, I don't know) this will be a foreign concept because heap-based objects and GC kills RAII. IMHO, being able to put objects on the stack is the greatest single advantage of C++ over Java and makes well-written C++ code MUCH cleaner than well-written Java code.

I only use it when I need to release something by the means of RAII and even then only when it should be released as early as I possibly can (releasing a lock for example).

Programming in Java I have quite often wanted to limit scope within a method, but it never occurred to me to use a label. Since I uppercase my labels when using them as the target of a break, using a mixed case labeled block like you have suggested is just what I have wanted on these occasions.
Often the code blocks are too short to break out into a small method, and often the code in a framework method (like startup(), or shutdown()) and it's actually better to keep the code together in one method.
Personally I hate the plain floating/dangling braces (though that's because we are a strict banner style indent shop), and I hate the comment marker:
// yuk!
some code
{
scoped code
}
more code
// also yuk!
some code
/* do xyz */ {
scoped code
}
some more code
// this I like
some code
DoXyz: {
scoped code
}
some more code
We considered using "if(true) {" because the Java spec specifically says these will be optimized away in compilation (as will the entire content of an if(false) - it's a debugging feature), but I hated that in the few places I tried it.
So I think your idea is a good one, not at all silly. I always thought I was the only one who wanted to do this.

Yes, I use this technique because of RAII. I also use this technique in plain C since it brings the variables closer together. Of course, I should be thinking about breaking up the functions even more.
One thing I do that is probably stylistically controversial is put the opening curly brace on the line of the declaration or put a comment right on it. I want to decrease the amount of wasted vertical space. This is based on the Google C++ Style Guide recommendation..
/// c++ code
/// references to boost::test
BOOST_TEST_CASE( curly_brace )
{
// init
MyClass instance_to_test( "initial", TestCase::STUFF ); {
instance_to_test.permutate(42u);
instance_to_test.rotate_left_face();
instance_to_test.top_gun();
}
{ // test check
const uint8_t kEXP_FAP_BOOST = 240u;
BOOST_CHECK_EQUAL( instance_to_test.get_fap_boost(), kEXP_FAP_BOOST);
}
}

I agree with agartzke. If you feel that you need to segment larger logical code blocks for readability, you should consider refactoring to clean up busy and cluttered members.

It has its place, but I don't think that doing it so that $foo can be one variable here and a different variable there, within the same function or other (logical, rather than lexical) scope is a good idea. Even though the compiler may understand that perfectly, it seems too likely to make life difficult for humans trying to read the code.

The company I'm working at has a static analysis policy to keep local variable declarations near the beginning of a function. Many times, the usage is many lines after the first line of a function so I cannot see the declaration and the first reference at the same time on the screen. What I do to 'circumvent' the policy is to keep the declaration near the reference, but provide additional scope by using curly braces. It increases indentation though, and some may argue that it makes the code uglier.

Related

Why not GOTO Statement? [closed]

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 am doing Masters in Software Engineering. From College to University i heard from my teachers and instructors that never use GOTO statement in Programming Language.According to
Software Engineering By D. Sundar
USE of goto statements makes a program unstructured and makes it very
difficult to understand.
and i also read the same in book by MICROSOFT on its first page that never use GOTO Statmement in Programming.
It always arises question in my mind that if we are instructed that never use GOTO Statement then why it is the part of many common programming languages ?
At least for some programming languages (none of which I'm the designer of, obviously) like C and C++, I imagine it's there because it
Closely models what the hardware really can do, which is kind of the goal in these languages.
Is sometimes actually useful and better than more "structured" approaches.
The most common example of when goto is often considered good is when doing nested error/resource management in C. See for instance the Linux kernel, a fairly large and successful C project which uses goto for this purpose.
You want to read the seminal "Go to statement considered harmful" by Edsger W. Dijkstra (1968!)
There is no goto statement in java. The Java keyword list specifies the goto keyword, but it is marked as "not used".
You instructed not to use goto because they want to teach you how to write code.
but sometimes goto can be useful.
when you want to break at once from a multi-level loop. you can add an exit condition to each step. and you can use goto endloop
look at this example: (psaudo code)
while(cond1){
while(cond2){
while(cond3){
if(want to break){
goto endloop
}
do something
if(want to break2){
goto endloop
}
}
do something
}
do something
}
endloop:
do something else
without the goto it may look like this:
while(cond1 && exitloopflag){
while(cond2 && exitloopflag){
while(cond3 && exitloopflag){
if(want to break){
exitloopflag = true;
break;
}
do something
if(want to break2){
exitloopflag = true;
break;
}
}
if(exitloopflag)
break;
do something
}
if(exitloopflag)
break;
do something
}
do something else
so we can argue which code readability is better...
The presence of goto in any modern programming language is largely vestigial, sort of like the human appendix. Its functionality has been replaced with conditional and looping control structures (if-then-else, for/while/loops, switch/case statements, etc.). It hangs around in languages like C and C++ because there are edge cases where it's still quite useful, such as breaking out of a deeply nested loop:
for (...)
{
for (...)
{
for(...)
{
...
// hit a fatal error, need to break out to outermost scope
goto whoopsiedoodle;
}
}
}
whoopsiedoodle:
...
However, its use is discouraged for a number of very good reasons: since it can branch either direction in a function, it can destroy the ability to debug code by simple inspection. For example, given the following snippet:
i = 1;
label: printf("i = %d\n", i);
What value gets printed for i? How many times will that print statement be executed? Until you account for every instance of goto label;, you can't know. Now, imagine the code is structured something like the following:
i = 0;
goto label;
foo: ...
...
i = 1;
label: printf("i = %d\n", i);
...
goto foo;
...
Now, imagine several dozen (or even several hundred) lines of code for each ... in the snippet above. Also imagine the presence of 10 or 11 other labels scattered throughout, with associated goto statements scattered largely at random. This is modeled after some real-world code I encountered early in my career. The only way to debug code like this is to trace the execution, line by line, accounting for every goto along the way. This code was badly written to begin with (a monolithic, 5000-line main function, literally hundreds of separate variables, some declared at file scope, some local to main, and other atrocities), but the use of goto was a force amplifier that turned merely bad code into an unmaintainable sludge. This code defined "brittle"; we literally could not change a single line of it without breaking something else.
Excessive use of goto can also hinder the compiler's ability to optimize code. Modern compilers are quite smart, and can take advantage of structured programming techniques to do effective branch prediction or unroll loops for real performance gains. Code like the above is almost impossible for the compiler to optimize. That real world code that the above snippet is modeled on? We tried to compile it with optimization flags turned on (gcc -O1). The compiler ate all available RAM, then it ate all available swap, causing a kernel panic.
We told the customer they would either need to buy faster hardware, or allow us to rewrite the entire thing from the keel up. They wound up buying faster hardware.
goto can be used effectively, as long as you obey the following rules:
Branch forward only.
Never branch into the body of a control structure (i.e., don't bypass the if, for, while, or switch condition).
Avoid branching over large sections of code.
Id like to give an explanation, why you should use GOTO very carefully.
I do not say GOTO is a bad statement at all, that is one of the reasons, why it is still implemented in C++ (and due to compatibility reasons to C), in JAVA its only reserved as a keyowrd.
I can show you examples where GOTO is the best solution (in my point of view)
But you should prevent using it due to the following reason:
(Taken, translated and modified by me, from the Book Ohne C Zu C++)
Imagine you play a game like Settlers of Catan, wherever you go, anyone has its own
rules.
That is ok, you just need to learn the rules and then you can play with them.
But what is if they will not teach u there rules, and just use it? you will loose the fun in gaming with
them very fast.
A goto statement is like a new Settler of Catan rule.
Programming is hard enough to understand when you can reliably assume that you start at >the top, execute 1 line at a time, going down, one line at a time.
Using a goto statement throws that assumption out the window, and all of the sudden, the "game! is uncertain. It's a new and uncertain rule.
In some languages, it is used for exception handling (e.g. VBA)
Java has goto as a keyword but it is doing nothing. I belivie they did this, that you can't name anything goto
However, in some cases goto can be useful!
goto is explicitly not allowed in Java. It is there in other languages because it is easy to implement as it is a simple instruction in machine code, not because it is a good idea.
BTW You can do something like a goto in Java. See if you can easily work out what this simple example does, and if you can't you are answering your own question. If it's obvious to you what this does and how it works, you have to consider than many would find this confusing.
FOUND: {
for(String s: list)
if(s.contains(like))
break FOUND;
System.out.println(like + " not found");
}
Goto statements model machine code; there are very limited flow-control constructs in machine code, and there is no way to write a significant machine code program without the equivalent of a goto.
The original high-level languages, such as COBOL and FORTRAN, had Gotos because that's how people knew to control their flow from doing machine code on their machines. The C language was also created with one, though years later, partially because that language was specifically created to be easy to compile to efficient machine code -- some of the C language constructs, such as the increment/decrement operators, are there because the machine for which C was originally created had those sub-operations in its machine code. It can be said that C is not a high-level language, it is a structured assembler (and there's nothing wrong with that, it was ahead of its time, and still highly useful).
What Dijkstra and others figured out, though, is that (1) it isn't necessary to have a goto if you have sufficient higher-level constructs for flow control, and (2) it is horribly error-prone. I remember reading that there were analyses of code that found that a goto statement was 9 times more likely to be in error than any other kind of statement.
It is ironic because it is not the least difficult to understand conceptually what the statement is doing; it's just that the uses programmers make of it too often turn out to make the program overall harder to understand.
Goto is permitted when we're jumping
out of a scope,
just next behind the scope close.
All other cases are invalid (jumping into a cycle, jumping into the middle of an if-block, jumping into another function, OMG, happy Halloween).
As there are several way to break a scope, like break, break label, return etc, there is no situation where pure goto must be used (except some early languages which does not support some of above, usually break label).
Other words, goto has not disappeared (it's impossible to write a program without changing the order of execution), we just make distinctions by using different keywords for different types of execution path. Goto now has special cases, which have own keywords. It also makes code easier to understand.

Which one of these approaches would yield the fastest runtime? [closed]

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 10 years ago.
I am in the midst of a short thought experiment and would love some assistance.
Consider a class that calculates some output according to a function that itself can be changed, but can only be changed according to a predetermined set.
Or, some list of functions:
double function1(double input){
//perform some operations
return output;
}
double function2(double input){
//perform some operations
return output;
}
double function3(double input){
//perform some operations
return output;
}
double function4... etc.
Now imagine that these functions are contained within some class that predetermined which function to use whenever the class is called to calculate on some value
Class Calculate{
int whichFunction = 2;
double calculate (double input){
//decide which function to use
switch(whichFunction){
case 1:
return function1(input);
break;
case 2:
return function2(input);
break;
case 3:
return function3(input);
break;
case 4... etc..
}
... predetermined functions here....
}
Of course the first idea in performing this is to just switch on the value and move on. But what if we instead of using a switch, simply changed the function to run?
i.e.
Class Calculate{
Func<double> whichFunction;
double calculate (double input){
return whichFunction.Invoke(input);
}
void setFunction(int functionNumber){
switch(whichFunction){
case 1:
whichFunction = function1;
case 2:
whichFunction = function2;
case 3:
whichFunction = function3;
case 4... etc..
}
... predetermined functions here....
}
Considering that which function you choose would change infrequently, or possibly even only be set once in the constructor, would avoiding the switch actually deliver a run time speed benefit or is the very act of invoking a function in this way negating the benefit.
Other possible alternatives:
Cascading if-else.... NO, likely the slowest approach.
Instead of using the Func<> generic, use a delegate.
Take advantage of events and simply reassign which function is assigned to the event.
Instead of using the Func<>, use a method pointer.
Any thoughts would be well appreciated!
It is extremely unlikely that the decision here will impact performance in any meaningful way. I would imagine that the function being performed is more likely to take more time than the logic for firing it in most cases.
Each of the code snippits you've mentioned will run extremely quickly, and even if one is quicker than another, it will not be by any significant margin. Pick whichever method is easiest for you to understand and maintain and then start looking elsewhere for performance gains if you find that your application is performing too slowly.
It's hard to make a recommendation without knowing the bigger picture. You might be constructing a calculator for instance and if so may wish to overload actual math operators for your functions.
If you're going with a few functions and only one of them may apply, then perhaps a layered
if () {} else if () {} else if () {}
... structure may serve you better (more popular interrogations up front) as the structure would exit excution the moment your condition was met.
And of course there is the short-circuit logic for && and || functions to consider. That short-circuit can save you loads of time depending what you're after.
The "right" answer is to actually measure & compare your options. The "pragmatic" answer is that unless you have a very large number of functions, it won't matter enough to be worth the time you've already spent thinking about this. The "logical" answer is that your second option does switch far less frequently so it should be faster though it is not thread-safe and is an awkward API that will lead to bugs down the road (callers either forgetting to set the function or setting it so often that it defeats the purpose)
POITROAE.
Use a profiler!
There are too many optimizations that are available to modern compilers to predict what will run the fastest in your situation. In general,
a function call is a series of ops on the stack and a jump to a location.
Some compilers jump for each case of a switch statement
Some make a jump table, which can be a blessing and a curse.
if you have variables in a scope local to the switch a stack frame may be set up.
etc etc etc... The cases are almost infinite.
That said, a switch statement with just a few lines of code in each case is likely faster than a function call.
Also, on X86, jumps and function calls can clear the caches and pipelines so you pay a good penalty for that too.
A profiler really is best for modern software.
The relative performance for your two examples will depend on the specific context:
In most cases, especially if calculate is called a lot of times, the multiple comparisons in the switch statement will result in many branches that will get executed many times, and potentially incorrectly predicted by the CPU. This would easily outweigh the cost of the function call in the Invoke version.
If function1..3 are short and could be inlined, then there could be a situation where the compiler could optimize the "switch" version to be slightly faster than the "Invoke" one, since there is no way to optimize away the functions in the latter.
My advice would be to use the "Invoke" version, as in most cases it will result in optimal performance.

Does anyone still use [goto] in C# and if so why? [closed]

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 was wondering whether anyone still uses the "goto" keyword syntax in C# and what possible reasons there are for doing so.
I tend to view any statements that cause the reader to jump around the code as bad practice but wondered whether there were any credible scenarios for using such a syntax?
Goto Keyword Definition
There are some (rare) cases where goto can actually improve readability. In fact, the documentation you linked to lists two examples:
A common use of goto is to transfer control to a specific switch-case label or the default label in a switch statement.
The goto statement is also useful to get out of deeply nested loops.
Here's an example for the latter one:
for (...) {
for (...) {
...
if (something)
goto end_of_loop;
}
}
end_of_loop:
Of course, there are other ways around this problem as well, such as refactoring the code into a function, using a dummy block around it, etc. (see this question for details). As a side note, the Java language designers decided to ban goto completely and introduce a labeled break statement instead.
I remember this part
switch (a)
{
case 3:
b = 7;
// We want to drop through into case 4, but C# doesn't let us
case 4:
c = 3;
break;
default:
b = 2;
c = 4;
break;
}
To something like this
switch (a)
{
case 3:
b = 7;
goto case 4;
case 4:
c = 3;
break;
default:
b = 2;
c = 4;
break;
}
Refer This
I use it extensively in Eduasync to show the kind of code that the compiler generates for you when using async methods in C# 5. You'd see the same thing in iterator blocks.
In "normal" code though, I can't remember the last time I used it...
The compiler uses goto statements in various pieces of generated code, for example in generated iterator block types (generated when using the yield return keyword - I'm pretty sure that the generated XML serialisation types also have a few goto statements in there somewhere too.
See Iterator block implementation details: auto-generated state machines for some more details on why / how the C# compiler handles this.
Other than generated code there isn't a good reason to use a goto statement in normal code - it makes the code harder to understand and as a result more error-prone. On the other hand using goto statements in generated code like this can simplify the generation process and is normally fine because nobody is going to read (or modify) the generated code and there is no chance of mistakes being made because a machine is doing the writing.
See Go-to statement considered harmful for an argument against goto as well as a classic piece of programming history.
I don't remember ever using goto. But maybe it improves the intent of a forever loop that you really never want to exit (no break, but you can still return or throw):
forever: {
// ...
goto forever;
}
Then again, a simple while (true) should suffice...
Also, you could use in a situation where you want the first iteration of a loop to start in the middle of the loop: look here for an example.
goto is great for breaking out of many loops where break would not work well (say upon error conditions), and as Kragen said goto is used by the compiler to generate switch statements and some other things as well.
The processor implements at least one jump instruction and I'm sure lots of statements use those in thier implementation or interpretation.
One of the good things about using a 3rd or 4th generation langauge is that these physical details are abstracted away from us. Whilst we should be mindful of the law of leaky abstraction I think that we should also use our tools as they are intended (sorry). If I were writing code and a goto seemed like a good idea, it would be time to refactor. The purpose of a structured language is to avoid these "jumps" and to create a logical flow in our engineering.
I should avoid the use of break but I can't overlook the performance benefit. However, if I have nested loops that mutually need to break it is time to refactor.
If anybody can propose a use of goto that seems better than refactoring I will gladly withdraw my answer.
I hope I'm not guilty of rushing to the "bike shed" here. Like Kragen says, whats good enough for Dijkstra is good enough for me.
Goto is never better. And continue, break (except in switch/case), (multiple) return, and throw should also be kept to the barest minimum. You never want to escape from the middle of nest loops. You always want the loop control statements have all the loop control. Indenting has information, and all these statement throw that information away. You might as well take out all the indenting.

Should I declare variables as close as possible to the scope where they will be used?

ReSharper usually suggests me that, and I'm still looking for a good reason of why to do that.
The only thing that came to my mind is that declaring it closer to the scope it will be used, can avoid initializing it in some cases where it isn't necessary (because a condition, etc.)
Something related with that is the following:
int temp;
foreach (var x in collection) {
temp = x.GetValue();
//Do something with temp
}
Is that really different than
foreach (var x in collection) {
int temp = x.GetValue();
//...
}
I mean, isn't the second code more expensive because it is allocating memory everytime? Or are both the same? Of course, after finished the loop, in the second code the garbage collector will take care about temp variable, but not in the first one...
Declaring as close as possible to use is a readability decision. Your example doesn't display it, but in longer methods it's hard to sift through the code to find the temp variable.
It's also a refactoring advantage. Declaring closer to source leads to easier refactoring later.
The cost of the second example is negligible. The only difference is that in the first example, temp will be available outside the scope of the for loop, and thus it will exist longer than if you declared it inside the for loop.
If you don't need temp outside the for loop, it shouldn't be declared outside that loop. Like others have said, readability and style are more at play here than performance and memory.
I agree that if you init a variable inside the scope that it's being used then you're helping the gc out, but I think the real reason is more to do with code maintenance best practices. It's sort of a way of reducing cognitive load on you or another developer coming back to the code after months (or years) of not looking at a particular block. Sure, IDE's help you discover things, but you still have to do the "go to definition" dance.
There is no performance benefits, I believe, but more of a coding style. Its more C programming style to declare it all at the beginning of the scope. There is more details here: Scope of variables in C#
Its a style personal preference thing to do with readability.
There are very few languages/systems where this will have any noticeable effect on performance.
I try to follow these two rules.
All the core attributes of a class should be defined together in one place. e.g. If you are handling an order then orderno, customerno, amount, sales tax etc. should be defined close together.
All the technical attributes which form part of the internal mechanics of the class such as iterators, flags, state varaibles should be defined close to thier usage.
Or to put it another business/external type data all defined in one place, technical/internal data defined close to usage.
The difference is a matter of coding style and one of such dispute that different coding standards have completely opposite rules. The conflict is still strongest in the C++ world where the C language forced variables to be declared at the beginning of a scope and so old-timers (like myself) were well accustomed to "looking at the beginning of the function" to find variables.
The C# style that you most often see is that variables come into existence right at the point where they are needed. This style limits the existence of the variable and minimizes the chance that you could mean some other variable accidentally. I find it very easy to read.
In the modern C# era, putting the declaration of variables at their first point of use is most clearly beneficial when combined with the both loved and hated var feature. Using var just isn't that useful unless you use it with an assignment that allows the compiler and readers to infer the type of the variable. The var feature encourages declaration with first use.
Me, I love var, and so you can guess which coding style I prefer!
I was always taught to declare your variables at the top of a function, class, etc. This makes it easier to read.

Why does C# allow {} code blocks without a preceding statement?

Why does C# allow code blocks without a preceding statement (e.g. if, else, for, while)?
void Main()
{
{ // any sense in this?
Console.Write("foo");
}
}
The { ... } has at least the side-effect of introducing a new scope for local variables.
I tend to use them in switch statements to provide a different scope for each case and in this way allowing me to define local variable with the same name at closest possible location of their use and to also denote that they are only valid at the case level.
In the context you give, there is no significance. Writing a constant string to the console is going to work the same way anywhere in program flow.1
Instead, you typically use them to restrict the scope of some local variables. This is further elaborated here and here. Look at João Angelo’s answer and Chris Wallis’s answer for brief examples. I believe the same applies to some other languages with C-style syntax as well, not that they’d be relevant to this question though.
1 Unless, of course, you decide to try to be funny and create your own Console class, with a Write() method that does something entirely unexpected.
It is not so much a feature of C# than it is a logical side-effect of many C syntax languages that use braces to define scope.
In your example the braces have no effect at all, but in the following code they define the scope, and therefore the visibility, of a variable:
This is allowed as i falls out of scope in the first block and is defined again in the next:
{
{
int i = 0;
}
{
int i = 0;
}
}
This is not allowed as i has fallen out of scope and is no longer visible in the outer scope:
{
{
int i = 0;
}
i = 1;
}
And so on and so on.
I consider {} as a statement that can contain several statements.
Consider an if statement that exists out of a boolean expression followed by one statement.
This would work:
if (true) Console.Write("FooBar");
This would work as well:
if (true)
{
Console.Write("Foo");
Console.Write("Bar");
}
If I'm not mistaken this is called a block statement.
Since {} can contain other statements it can also contain other {}.
The scope of a variable is defined by it's parent {} (block statement).
The point that I'm trying to make is that {} is just a statement, so it doesn't require an if or whatever...
The general rule in C-syntax languages is "anything between { } should be treated as a single statement, and it can go wherever a single statement could":
After an if.
After a for, while or do.
Anywhere in code.
For all intents and purposes, it's as the language grammar included this:
<statement> :== <definition of valid statement> | "{" <statement-list> "}"
<statement-list> :== <statement> | <statement-list> <statement>
That is, "a statement can be composed of (various things) or of an opening brace, followed by a statement list (which may include one or more statements), followed by a closed brace". I.E. "a { } block can replace any statement, anywhere". Including in the middle of code.
Not allowing a { } block anywhere a single statement can go would actually have made the language definition more complex.
Because C++ (and java) allowed code blocks without a preceding statement.
C++ allowed them because C did.
You could say it all comes down to the fact that USA programme language (C based) design won rather than European programme language (Modula-2 based) design.
(Control statements act on a single statement, statements can be groups to create new statements)
// if (a == b)
// if (a != b)
{
// do something
}
1Because...Its Maintain the Scope Area of the
statement.. or Function, This is really useful for mane the large code..
{
{
// Here this 'i' is we can use for this scope only and out side of this scope we can't get this 'i' variable.
int i = 0;
}
{
int i = 0;
}
}
You asked "why" C# allows code blocks without preceeding statements. The question "why" could also be interpreted as "what would be possible benefits of this construct?"
Personally, I use statement-less code blocks in C# where readability is greatly improved for other developers, while keeping in mind that the code block limits the scope of local variables. For example, consider the following code snippet, which is a lot easier to read thanks to the additional code blocks:
OrgUnit world = new OrgUnit() { Name = "World" };
{
OrgUnit europe = new OrgUnit() { Name = "Europe" };
world.SubUnits.Add(europe);
{
OrgUnit germany = new OrgUnit() { Name = "Germany" };
europe.SubUnits.Add(germany);
//...etc.
}
}
//...commit structure to DB here
I'm aware that this could be solved more elegantly by using methods for each structure level. But then again, keep in mind that things like sample data seeders usually need to be quick.
So even though the code above is executed linearly, the code structure represents the "real-world" structure of the objects, thus making it easier for other developers to understand, maintain and extend.

Categories