C Switch-case curly braces after every case - c

In a C switch-case flow control, it's required to put curly braces { } after a case if variables are being defined in that block.
Is it bad practice to put curly braces after every case, regardless of variable declaration?
For example:
switch(i) {
case 1: {
int j = 4;
...code...
} break;
case 2: { //No variable being declared! Brace OK?
...code...
} break;
}

It's certainly not invalid to use braces in every case block, and it's not necessarily bad style either. If you have some case blocks with braces due to variable declarations, adding braces to the others can make the coding style more consistent.
That being said, it's probably not a good idea to declare variables inside case blocks in straight C. While that might be allowed by your compiler, there's probably a cleaner solution. Mutually-exclusive case blocks may be able to share several common temporary variables, or you may find that your case blocks would work better as helper functions.

Braces may be used in every case statement without any speed penalty, due to the way compilers optimize code. So it's just the style and the preference of the coder.
The most preferred usage is not using braces, though the usage of them in every case during an active development may be found easier to make some additions on the code every now and then.
It's just the easthetics; because a 'case' statement doesn't need only a single command, but will walk through the code as it works as a label. So blocks are not needed, and are not invalid.
In 'case's with variables; braces are used just-in-case, to create contexts for variables, and it makes big sense to use them. Some compilers on different platforms show different behaviours if they are not included.

I consider it bad style to use braces in each case. Cases are labels in C, akin to goto labels. And in the current C language, you're free to declare variables in each case (or anywhere you like) without introducing new blocks, though some people (myself included) also consider that bad style.

Generally it is bad practice jump over the initialization of a variable, be it with goto or switch. This is what happens when you don't have the the blocks per case.
There is even a case in C99 where jumping over the initialization is illegal, namely variable length arrays. They must be "constructed" similarly as non-PODs in C++, their initialization is necessary for the access of the variable later. So in this case you must use the block statement.

Just to add a minor point many editors & IDEs allow blocks to be collapsed and/or auto indented and several allow you to jump to the matching brace - I personally don't know of any that allow you to jump from a break to the matching case statement.
When debugging, or re-factoring, other peoples, (or even your own after a few months), code that contains complex case statements the ability to both collapse sections of the code and to jump to matching cases is invaluable, especially if the code contains indentation variations.
That said it is almost always good advice to avoid complex case statements like the plague.

Related

Bison: How to check if continue/break are in a loop?

I have the following fragment in my Bison file that describes a simple "while" loop as a condition followed by a sequence of statements. The list of statements is large and includes BREAK and CONTINUE. The latter two can be used only within a loop.
%start statements
%%
statements: | statement statements
statement: loop | BREAK | CONTINUE | WRITE | ...
loop: WHILE condition statements ENDWHILE
condition: ...
%%
I can add a C variable, set it upon entering the loop, reset it upon exiting, and check at BREAK or CONTINUE, but this solution does not look elegant:
loop: WHILE {loop++;} condition statements {loop--;} ENDWHILE
statement: loop | BREAK {if (!loop) yyerror();} ...
Is there a way to prevent the two statements from outside a loop using only Bison rules?
P.S. What I mean is "Is there an EASY way..," without fully duplicating the grammar.
Sure. You just need three different statement non-terminals, one which matches all statements; one which matches everything but continue (for switch blocks), and one which matches everything but break and continue. Of course, this distinction needs to trickle down through your rules. You'll also need three versions of each type of compound statement: loops, conditionals, switch, braced blocks, and so on. Oh, and don't forget that statements can be labelled, so there are some more non-terminals to duplicate.
But yeah, it can certainly be done. The question is, is it worth going to all that trouble. Or, to put it another way, what do you get out of it?
To start with, the end user finds that where they used to have a pretty informative error message about continue statements outside a loop, they now just get a generic Syntax Error. Now, you can fix that with some more grammar modifications, by actually providing productions which match the invalid statements, and then present a meaningful error message. But that's almost exactly the same code already rejected as inelegant.
Other than that, does it in any way reduce parser complexity? It lets you assume that a break statement is legally placed, but you still have to figure out where the break statement's destination. And other than that, there's not really a lot of evident advantages, IMHO.
But if you want to do it, go for it.
Once you've done that, you could try modifying your grammar so that break, continue, goto and return cannot be followed by an unlabelled statement. That sounds like a good idea, and some languages do it. It can certainly be done in the grammar. (But before you get too enthusiastic, remember that some programmers do deliberately create dead code during debugging sessions, and they won't thank you for making it impossible.)
There is a BNF extension, used in the ECMAscript standard, amongst others, which parameterizes non-terminals with a list of features, each of which can be present or not. These parameters can then be used in productions, either as conditions or to be passed through to non-terminals on the right-hand side. This could be used to generate three versions of statement, using the features [continue] and [break], which would be used as gates on those respective statement syntaxes, and also passed through to the compound statement non-terminals.
I don't know of a parser generator capable of handling such parameterised rules, so I can't offer it as a concrete suggestion, but this question is one of the use cases which motivated parameterised non-terminals. (In fact, I believe it's one of the uses, but I might be remembering that wrong.)
With an ECMAScript-style formalism, this grammatical restriction could be written without duplicating rules. The duplication would still be there, under the surface, since the parser generator would have to macro expand the templated rules into their various boolean possibilities. But the grammar is a lot more readable and the size of the state machine is not so important these days.
I have no doubt that it would be a useful feature, but I also suspect that it would be overused, with the result that the quality of error messages would be reduced.
As a general rule, compilers should be optimised for correct inputs, with the additional goal of producing helpful error messages for invalid input. Complicating the grammar even a little to make easily described errors into syntax errors does not help with either of these goals. If it's possible to write a few lines of code to produce the correct error message for a detected problem, instead of emitting a generic syntax error, I would definitely do that.
There are (many) other use cases for the ECMAScript BNF extensions. For example they make it much easier to describe a syntax whose naive grammar requires two or three lookahead tokens.

Why did the creators of C decide to support one statement while loops without braces?

I am reading The C Programming Language (K&R) and noticed C allows the use of while loops preceding a single statement to function without any braces; why did the creators of C decide to support this? I presume this introduces some extra complexity for the compiler, is the desire for single statement while loops so common (for readability, perhaps?) it was worth whatever trade-off was required to allow them?
It doesn't add any special complexity to the compiler, and it's not just while loops. All of the control structures (if, for, while, etc.) govern a "statement", where a block is just a special case of a statement (called a "compound-statement") containing 0 or more declarations or statements. There isn't any specific use case or rationale for applying this rule to while, but none is really needed, other than maybe simplicity or consistency.

Why does C allow leaving out braces around blocks? [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 7 years ago.
Improve this question
Most of us have probably encountered the bug of when you add another statement inside an 'if' and notice that it prints regardless of the condition of the branch, only to find out sooner or later in frustration that the braces around the 'if' condition was missing.
Example:
if (condition) {
statement;
}
Compared to:
if (condition)
statement;
Please note that I wouldn't want a discussion on what coding standard is better, as we all have our opinion about that and it's very much dependent on context. Instead, I would be interested in the advantages from a programming language point of view and from these advantages, why it was decided not to be strictly enforced. Does it make for a simpler grammar? Compiler implementation?
What is the advantage of leaving it optional, rather than strictly enforcing it? What does the standard say about it?
The C Standard says that a if (expression) must be followed by a statement. It does not require the statement to be a compound statement.
In the "Spirit of C" (see C Rationale document), one of the phrase is:
Trust the programmer.
MISRA-C on the other hand has a required rule for if and loops that the statement has to be a compound statement.
Some coding styles allow a single statement for if only if the statement is put in the same line as the if. For example:
if (condition) statement;
Note that C and C++ are not only the languages to have the {} be optional in if. For example in Java it is also optional, but in Perl it is required.
Because:
that would be excessive meddling — the programmer chooses coding style, not the language;
it would further complicate the grammar; easier and more robust to just say that an if (condition) is followed by a statement and let the recursion handle everything.
Personally I find the distrust of this construct to be largely without merit for any vaguely competent programmer; I've not once encountered this "bug" where I've forgotten how to write C++ just because I chose to omit a brace pair. If you come across it, I suggest you treat it as a cue to pay more attention to what you're doing, rather than masking it with "tricks" and "style guides".
Sometimes, not having to write the braces makes the code more readable imho:
if (x < 0) throw std::invalid_argument("meh");
if (a != b) return 0;
if (i == k) continue;
In theory, you could design a programming language to require braces except for control flow statements, but this safety would probably be outweighed by the additional language complexity.
C/C++ also doesn't mandate strict adherence to K&R style. For people who prefer Allman style, the extra braces are completely unnecessary:
if (condition)
statement;
if (condition)
{
statement;
statement;
}
With the introduction of lambdas and braced initialization, we are seeing an increasing number of braces in our code and I think Allman style actually manages it better.
You misunderstand it slightly. The braces are neither optional nor compulsory. There was no decision about whether to allow them or to enforce them at all. The braces are not part of the if statement (or any similar construct). They belong to the statement that follows the condition. Simple statements will not have them but compound statements will (by definition, a compound statement is a list of statements enclosed in braces).
This situation and how the compiler handles it comes directly from this syntax definition (which is, actually, nothing C-specific, most other languages of the era that I can think of, Algol, Pascal, whatever, even if they used keywords instead of braces, do the very same). Basically, any language that has no specific ending keywords (like if and end if or if and fi) have to handle it this way.
When you do include the braces around a single statement in an if or any other similar construct, you don't use an optional form of if allowing braces. You just happen to provide it with a compound statement (hence, enclosed in braces) consisting only of a single statement inside, and this is perfectly legal. But it's the same for the compiler, it doesn't handle it any different.
Actually, but this is a question of taste, of course, many programmers prefer to omit them because it reduces clutter.
A scope is merely a compound statement. It can be placed anywhere:
void foo() {
int a = 0;
a = 1; // this is a simple statement.
{ // this is inside a scope. It is a compound statement. Note that I don't need an if.
a = 2;
a++;
}
return a;
}
Being able to put any statement (compound or not) after an if, while or other constructs makes the syntax much simpler to implement.
C was created in a time when computers had 40×25 character graphics.
If you want to have indentation of the condition block/statement
you save one (opening brace on the same line) or two lines (opening brace on the following line):
if (condition)
statement;
if (condition) {
statement;
}
if (condition)
{
statement;
}
So saving a line was important. It allowed to show more source code in one screen.

something unclear about switch-case

Something about switch-case statement is very unclear for me. First of all I could understand the case part as an if statement, but what dose switch do itself? I mean when we pass argument to switch, what happens there?
c=getchar();
switch(c)
2: Why there is no need to put ; after switch? What kind of the function is it?
3: How compilers implement switch-case statement at the first time? (just C or use assembly)
4: We can't use switch-case like this:
switch(string)
{
case "aaaa":
...
case "bbbb":
...
we use if-strcmp instead. Is it possible to create switch-case like statement for string condition? I see some library like getopt use struct to handle command line string arguments:
{"help",...,'h'},
{"version",...,'v'}
...
but I want to use string directly.
first of all I could understand "case" part as a "if" statement, but what dose switch do itself? I mean when we pass argument to switch, what happens there?
In case, there's always a constant. You need to "compare" something with this constant. And switch(a) means - "compare a with:" and it "compares" it to each case statement.
2: why there is no need to put ";" after switch? what kind of the function is it?
It's not a function. You're not calling switch function, you're just starting to write a switch statement.
3: how compilers implement switch-case statement at the first time? (just C or use assembly)
That's platform specific. Sometimes, it's implemented using jumps (asm) and offsets.
4: we can't use switch-case like this:
Because switch works only with integral types (that is int, enum, char, etc. and not double, strings, etc.)
The switch statement begins the scope of the cases. Scopes in C/C++ are always bound by curly braces ( {} ), specifying the scope of local variables (on the stack) which is used to hold the switch parameter. It hence doesn't need a ; since it is grammatically much like a while loop.
Compilers implement switchs as direct jump in assembly. This is what makes them really more efficient than ifs (which are mostly compiled as different comparisons in assembly). This is also the reason why you can't use a switch on text. The value of a char* is only a pointer, hence cannot be used to correctly identify the target section to execute.
To use strings in switch case() in c what you can do is, to store the possible strings of switch in a string as
char * switchstr[]={"abc", "def", "ghi"};
then search for the input string in the switchstr[] and use the index of matching string as switch case parameter.
And to know why strings are not supported in switch case read this answer. IT has discussion about why string cant be used directly in switch statement in C/C++.
And also switch case checks for equality and we know in C it is not possible to check the equality of string directly by using = sign, instead we need to use strcmp() function.
first of all I could understand "case" part as a "if" statement, but what dose switch do itself?
The switch part sets the expression that is used to compare with the values in the associated case labels.
2: why there is no need to put ";" after switch? what kind of the function is it?
It is not a function; switch is a language keyword that is part of the switch statement (i.e. the whole switch/case construct). It is not a function just because it uses parentheses any more than while(...) or if(...) are functions.
3: how compilers implement switch-case statement at the first time? (just C or use assembly)
That is up to the compiler. How things are implemented is generally not within the purview of a language standard, only (as precisely as possible) what should happen.
In practice, a switch statements tend to be implemented with branches if there are only a few cases, and with a jump table if there are many.
4: we can't use switch-case [with strings]
Because C defines the switch statement as working with integral types. A string is not an integral type. To provide the kind of functionality you envisage would require adding (at least) “content equality” testing for strings to the core C language. To do this consistently in a way that does not break existing code is probably impossible and contrary to the “minimalist” philosophy of C.

Do you use curly braces for additional scoping? [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 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.

Resources