Elegant way for exiting a function neatly without using goto in C - c

We often write some functions which have more than one exit point (that is, return in C). At the same time, when exiting the function, for some general works such as resource cleanup, we wish to implement them only once, rather than implementing them at every exit point. Typically, we may achieve our wish by using goto like the following:
void f()
{
...
...{..{... if(exit_cond) goto f_exit; }..}..
...
f_exit:
some general work such as cleanup
}
I think using goto here is acceptable, and I know many people agree on using goto here. Just out of curiosity, does there exist any elegant way for neatly exiting a function without using goto in C?

Why avoid goto?
The problem you want to solve is: How to make sure some common code always gets executed before the function returns to the caller? This is an issue for C programmers, since C does not provide any built in support for RAII.
As you already concede in your question body, goto is a perfectly acceptable solution. Never-the-less, there may be non-technical reasons to avoid using it:
academic exercise
coding standard compliance
personal whim (which I think is what is motivating this question)
There are always more than one way to skin a cat, but elegance as a criteria is too subjective to provide a way to narrow to a single best alternative. You have to decide the best option for yourself.
Explicitly calling a cleanup function
If avoiding an explicit jump (e.g., goto or break) common cleanup code can be encapsulated within a function, and explicitly called at the point of early return.
int foo () {
...
if (SOME_ERROR) {
return foo_cleanup(SOME_ERROR_CODE, ...);
}
...
}
(This is similar to another posted answer, that I only saw after I initially posted, but the form shown here can take advantage of sibling call optimizations.)
Some people feel explicitness is more clear, and therefore more elegant. Others feel the need to pass cleanup arguments to the function to be a major detractor.
Add another layer of indirection.
Without changing the semantics of the user API, change its implementation into a wrapper composed of two parts. Part one performs the actual work of the function. Part two performs the cleanup necessary after part one is done. If each part is encapsulated within its own function, the wrapper function has a very clean implementation.
struct bar_stuff {...};
static int bar_work (struct bar_stuff *stuff) {
...
if (SOME_ERROR) return SOME_ERROR_CODE;
...
}
int bar () {
struct bar_stuff stuff = {};
int r = bar_work(&stuff);
return bar_cleanup(r, &stuff);
}
The "implicit" nature of the cleanup from the point of view of the function that performs the work may be viewed favorably by some. Some potential code bloat is also avoided by only calling the cleanup function from a single place. Some argue that "implicit" behaviors are "tricky", and therefore more difficult to understand and maintain.
Miscellaneous...
More esoteric solutions using setjmp()/longjmp() can be considered, but using them correctly can be difficult. There are open-source wrappers that implement try/catch exception handling style macros over them (for example, cexcept), but you have to change your coding style to use that style for error handling.
One could also consider implementing the function like a state machine. The function tracks progress through each state, an error causes the function to short circuit to the cleanup state. This style is usually reserved for particularly complex functions, or functions that need to be retried later and be able to pick up from where they left off.
Do as the Romans do.
If you need to comply to coding standards, then the best approach is to follow whatever technique is most prevalent in the existing code base. This applies to almost all aspects of making changes to an existing stable source code base. It would be considered disruptive to introduce a new coding style. You should seek approval from the powers that be if you feel a change would dramatically improve some aspect of the software. Otherwise, as "elegance" is subjective, arguing for the sake of "elegance" is not going to get you anywhere.

For example
void f()
{
do
{
...
...{..{... if(exit_cond) break; }..}..
...
} while ( 0 );
some general work such as cleanup
}
Or you could use the following structure
while ( 1 )
{
//...
}
The main advantage of the structural approach contrary to using goto statements is that it introduces a discipline in writing code.
I am sure and have enough experience that if a function has one goto statement then through some time it will have several goto statements.:)

I've seen a lot of solutions how to do this and they tend to be obscure, unreadable and ugly at some degree.
I personally think the least ugly way is this:
int func (void)
{
if(some_error)
{
cleanup();
return result;
}
...
if(some_other_error)
{
cleanup();
return result;
}
...
cleanup();
return result;
}
Yes, it uses two rows of code instead of one. So? It is clear, readable, maintainable. This is a perfect example of where you have to fight your knee-jerk reflexes against code repetition and use common sense. The cleanup function is written only once, all clean up code is centralized there.

I think the question is very interesting, but cannot be answered without being influenced by subjectivity because elegance is subjective. My ideas on it are as follows: In general, what you want to do in the scenario you describe, is to prevent control from passing through a series of statements along the execution path. Other languages would do this by raising an exception, which you would have to catch.
I had already written down neat hacks to do what you want to do with pretty much every control statement there is in C, sometimes in combination, but I think they are all just very obscure ways of expressing the idea of skipping to a special point. Instead I'll just make my point on how we arrive at a point where goto can be preferable : Once again, what you want to express using is that something has occurred that prevents following the regular execution path. Something that is not just a regular condition that can be handled by taking a different branch down the path, but something makes it impossible to use the path to the regular return point in a safe way in the current state. I think there are three options to proceed at that point:
return through a conditional clause
goto an error-label
every statement that could fail is inside a conditional statement, and regular execution is considered a series of conditional operations.
If your cleanup is similar enough on every possible emergency exit I would prefer the goto, because writing the code redundantly just clutters the function. I think you should trade the number of return points and replicated clean-up code that you create against the awkwardness of using a goto. Both solutions should be accepted as a personal choice of the programmer, unless there are severe reasons for not doing so, e.g. you agreed that all functions must have a single exit. However, the use of either should be consequent and consistent across the code. The third alternative is - imo - the less readable cousin of the goto, because, in the end you will skip to a set of cleanup routines - possibly enclosed by else-statements too, but it makes it much harder for humans to follow the regular flow of you program, due to the deep nesting of conditional statements.
tl;dr: I think choosing between conditional return and goto based on consequent style-decisions is the most elegant way, because it is the most expressive way to represent your ideas behind the code and clarity is elegance.

I guess that elegant may mean for you weird and that you simply want to avoid the goto keyword, so....
You might consider using setjmp(3) and longjmp :
void foo() {
jmp_buf jb;
if (setjmp(jb) == 0) {
some_stuff();
//// etc...
if (bad_thing() {
longjmp(jb, 1);
}
};
};
I have no idea if it fits your elegance criteria. (I believe it is not very elegant, but this is only an opinion; however, there is no explicit goto).
However, the interesting thing is that longjmp is a non-local jump : You could have passed (indirectly) jb to some_stuff and have some other routine (e.g. called by some_stuff) do the longjmp. This may become unreadable code (so comment it wisely).
Even uglier than longjmp : use (on Linux) setcontext(3)
Read about continuations and exceptions (and the call/cc operation in Scheme).
And of course, the standard exit(3) is an elegant (and useful) way to go out of some function. You could sometimes play neat trick by also using atexit(3)
BTW, Linux kernel code uses quite often goto including in some code which is considered as elegant.
My point is : IMHO don't be fanatic against goto-s since there are cases where using (with care) it is in fact elegant.

I'm a fan of:
void foo(exp)
{
if( ate_breakfast(exp)
&& tied_shoes(exp)
&& finished_homework(exp)
)
{
good_to_go(exp);
}
else
{
fix_the_problems(exp);
}
}
Where ate_breakfast, tied_shoes, and finished_homework take a pointer to exp that they work on, and return bools indicating a failure of that particular test.
It helps to remember that short circuit evaluation is at work here - Which may qualify as a code smell to some people, but like everybody else has been saying, elegance is somewhat subjective.

goto statement is never necessary, also it is easier to write code without using it.
Instead you can use a cleaner function and return.
if(exit_cond) {
clean_the_mess();
return;
}
Or you can break as Vlad mentioned above. But one drawback of that, if your loop has deeply nested structure break will only exit from innermost loop.
For example:
While ( exp ) {
for (exp; exp; exp) {
for (exp; exp; exp) {
if(exit_cond) {
clean_the_mess();
break;
}
}
}
}
will only exit from inner for loop and doesn't abandon process.

Related

Using function parameter as variable

Is it bad or good practice or maybe undefined behavior to re-assign function parameter inside function?
Let me explain what I'm trying to do with an example, here the function:
void
gkUpdateTransforms(GkNode *node /* other params */) {
GkNode *nodei;
if (!(nodei = node->chld))
return;
do {
/* do job */
nodei = nodei->next;
} while (nodei);
}
Alternative:
void
gkUpdateTransforms2(GkNode *node /* other params */) {
/* node parameter is only used here to get chld, not anywhere else */
if (!(node = node->chld))
return;
do {
/* do job */
node = node->next;
} while (node);
}
I checked assembly output and it seems same, we don't need to declare a variable in second one. You may ask what if parameter type changed but same condition would be same for first one, because it also need to be updated.
EDIT: Parameters are pass-by-value, and my intention is not edit pointer itself
EDIT2: What about recursive functions? What would happen if gkUpdateTransforms2 was recursive? I'm confused because function will call itself but I think in every call, parameters will be different stack
I have no idea why you think this would be undefined behavior - it is not. Mostly it is a matter of coding style, there's no obvious right or wrong.
Generally, it is good practice to regard parameters as immutable objects. It is useful to preserve an untouched copy of the input to the function. For that reason, it may be a good idea to use a local variable which is just a copy of the parameter. As you can see, this does not affect performance the slightest - the compiler will optimize the code.
However, it is not a big deal if you write to the parameters either. This is common practice too. Calling it bad practice to do so would be very pedantic.
Some pedantic coding styles make all function parameters const if they shouldn't be modified, but I personally think that's just obfuscation, which makes the code harder to read. In your case such pedantic style would be void gkUpdateTransforms(GkNode*const node). Not to be confused with const correctness, which is an universally good thing and not just a style matter.
However, there is something in your code which is definitely considered bad practice, and that is assignment inside conditions. Avoid this whenever possible, it is dangerous and makes the code harder to read. Most often there is no benefit.
The danger of mixing up = and == was noted early on in the history of C. To counter this, in the 1980s people came up with brain-damaged things like the "yoda conditions". Then around 1989 came Borland Turbo C which had a fancy warning feature "possible incorrect assignment". That was the death of the Yoda conditions, and compilers since then have warned against assignment in conditions.
Make sure that your current compiler gives a warning for this. That is, make sure not to use a worse compiler than Borland Turbo from 1989. Yes, there are worse compilers on the market.
(gcc gives "warning: suggest parentheses around assignment used as truth value")
I would write the code as
void gkUpdateTransforms(GkNode* node /* other params */)
{
if(node == NULL)
{
return ;
}
for(GkNode* i=node->chld; i!=NULL; i=i->next;)
{
/* do job */
}
}
This is mostly stylistic changes to make the code more readable. It does not improve performance much.
IMHO it is not exactly "bad" practice but it is worthwile to question oneself if there isn't a better way. About your analyzing the assembler output: it may serve as an interesting and educational look behind the curtain but you are ill advised to use this as an justification for optimization or worse, laziness in the source code. The next compiler or the next architecture may just render your musings completely invalid - my recommendation is to stay with Knuth here: "Instead of imagining that our main task is to instruct a computer what to do, let us concentrate rather on explaining to human beings what we want a computer to do.".
In your code I think the decision is 50:50 with no clear winner. I would deem the node-iterator a concept of its own, justifying a separate programming construct (which in our case is just a variable) but then again the function is so simple that we don't win much in terms of clarity for the next programmer looking at your code, so we can very well live with the second version. If your function starts to mutate and grow over time, this premise may become invalid and we were better off the first version.
That said, I would code the first version like this:
void
gkUpdateTransforms(GkNode *node /* other params */) {
for (GkNode *nodei = node->chld; nodei != NULL; nodei = nodei->next) {
/* do job */
}
}
This is well defined and a perfectly good way to implement this behaviour.
The reason you might see it as an issue is the common mistake of doing the following:
int func(object a) {
modify a // only modifying copy, but user expects a to be modified
But in your case, you expect to make a copy of the pointer.
As long as it's passed by value, it can be safely treated as any other local variable. Not a bad practice in this scenario, and not undefined behaviour either.

Using C preprocessor macros for function naming idiomatic?

I'm writing a Scheme interpreter. For each built-in type (integer, character, string, etc) I want to have the read and print functions named consistently:
READ_ERROR Scheme_read_integer(FILE *in, Value *val);
READ_ERROR Scheme_read_character(FILE *in, Value *val);
I want to ensure consistency in the naming of these functions
#define SCHEME_READ(type_) Scheme_read_##type_
#define DEF_READER(type_, in_strm_, val_) READ_ERROR SCHEME_READ(type_)(FILE *in_strm_, Value *val_)
So that now, instead of the above, in code I can write
DEF_READER(integer, in, val)
{
// Code here ...
}
DEF_READER(character, in, val)
{
// Code here ...
}
and
if (SOME_ERROR != SCHEME_READ(integer)(stdin, my_value)) do_stuff(); // etc.
Now is this considered an unidiomatic use of the preprocessor? Am I shooting myself in the foot somewhere unknowingly? Should I instead just go ahead and use the explicit names of the functions?
If not are there examples in the wild of this sort of thing done well?
I've seen this done extensively in a project, and there's a severe danger of foot-shooting going on.
The problem happens when you try to maintain the code. Even though your macro-ized function definitions are all neat and tidy, under the covers you get function names like Scheme_read_integer. Where this can become an issue is when something like Scheme_read_integer appears on a crash stack. If someone does a search of the source pack for Scheme_read_integer, they won't find it. This can cause great pain and gnashing of teeth ;)
If you're the only developer, and the code base isn't that big, and you remember using this technique years down the road and/or it's well documented, you may not have an issue. In my case it was a very large code base, poorly documented, with none of the original developers around. The result was much tooth-gnashing.
I'd go out on a limb and suggest using a C++ template, but I'm guessing that's not an option since you specifically mentioned C.
Hope this helps.
I'm usually a big fan of macros, but you should probably consider inlined wrapper functions instead. They will add negligible runtime overhead and will appear in stack backtraces, etc., when you're debugging.

C Unit Testing - Returning from a stubbed graceful exit routine

Here is the scenario I've got. The function I'm testing has an error condition that, if hit, calls a graceful exit function to free any global memory, close handles, and exit the program.
Obviously, I'll want to write a test that tickles this condition to make sure that it is handled correctly but I don't want the graceful exit routine to actually exit the program since that would stop any remaining tests. This means stubbing the graceful exit routine. The problem with stubbing and not calling exit is that the flow of control returns to the function under test (which is bad since the routine was supposed to exit).
Here is the actual question: How do we return control from the stubbed function to the test instead of to the function under test?
I can do a setjmp / longjmp, but since "gotos" are bad in general, I'd love any other suggestions. (Keep in mind that this is procedural C, not C++, so exceptions aren't going to work as far as I know)
EDIT
As Soren and others have suggested below, making exit do nothing when testing is a great idea. There are several ways to do this whether it be through a #define statement or a stub for the exit() routine.
HOWEVER, doing so presents the problem that I'm really after a solution for (other than setjmp / longjmp). Take a look at this scenario:
void gracefulExit() {
// Clean Up
exit();
}
void routineUnderTest() {
// Do some calcs
if (someBadCondition == TRUE)
gracefulExit()
// Do some more calcs
}
If exit() does nothing in this scenario, gracefulExit() will return control back to the routine under test, which should not happen. Hence, I need a way to make exit() (or the stubbed version of gracefulExit()) return control to the test instead of the function under test.
setjmp / longjmp (aka goto) is a way to do this, although not really an elegant way. Any ideas on how to solve that?
EDIT #2
As fizzer mentioned, setjmp/longjmp is a valid way to handle this situation. It is the likely way that I will handle it permanently.
I have, however, received another possible solution from a co-worker. Instead of #defining the gracefulExit() routine to a stub routine, do the following:
#define gracefulExit return NULL
The particular function under test handles this just fine since NULL is a valid return value for it. I haven't tested this in every possible case yet (e.g. a function that has a void return value). As mentioned earlier, I will likely use the setjmp/longjmp way of solving this problem, but if this additional solution sparks an idea for somebody, great!
I would suggest your clean-up method creates an unpublished interface to do the exit.
so
void (*exitfunc((int) = exit;
void myCleanUp() {
.... do the cleanup
(*exitfunc)(-1); // this will in normal operation call exit
}
and in your unit test code, you "override" the exit function as
void donothing(int exitcode) {}
unittest(){
extern void (*exitfunc((int);
exitfunc = donothing; // or use a longjump if clean exit cannot be made without
... do the test.....
This would mean that your code compiles to the same whether in a unit test or somewhere else, and the difference in behaviour is only occuring when you execute the unit-test. The alternatives using conditional compiling for unit testing means that you will end up with .o files where you don't know if they were intended for test or production, and you will have bad stuff happening to your project.
I use setjmp / longjmp (wrapped in a convenience macro) for this and similar scenarios (e.g. test that an assertion failed).
You may be able to achieve this through the use of weak symbols, if your platform supports them.
You would write two versions of the graceful_exit() function, one used by the normal application defined as a weak symbol, and another used when running under your unit-test framework defined normally.
The intention would be that if you are linking against your unit-test code that the strong version of the function would be used instead of the weak version.
This has the benefit that no conditional compilation is required to support your unit-testing.
There is a useful discussion on the use of weak symbols in this question.
You might consider using a #define block to specify when your "cleanup and exit" routines are run and only compile this in when building for production or release. That way, you could still see if the condition hits, but it won't actually execute the code.
like jonfen said, I think that using the preprocessor is the way to do it. Something like:
if (bad_stuff_happened) {
do_cleanup();
#ifdef UNIT_TEST
return;
#endif
}

good c style when checking lots of return values

Sometimes I have to write code that alternates between doing things and checking for error conditions (e.g., call a library function, check its return value, keep going). This often leads to long runs where the actual work is happening in the conditions of if statements, like
if(! (data = (big_struct *) malloc(sizeof(*data)))){
//report allocation error
} else if(init_big_struct(data)){
//handle initialization error
} else ...
How do you guys write this kind of code? I've checked a few style guides, but they seem more concerned with variable naming and whitespace.
Links to style guides welcome.
Edit: in case it's not clear, I'm dissatisfied with the legibility of this style and looking for something better.
Though it pains me to say it, this might be a case for the never-popular goto. Here's one link I found on on the subject: http://eli.thegreenplace.net/2009/04/27/using-goto-for-error-handling-in-c/
I usually write that code in this way:
data = (big_struct *) malloc(sizeof(*data));
if(!data){
//report allocation error
return ...;
}
err = init_big_struct(data);
if(err){
//handle initialization error
return ...;
}
...
In this way I avoid calling functions inside if and the debug is easier because you can check the return values.
Dont use assert in production code.
In debug mode, assert should never be used for something that can actually happen (like malloc returning NULL), rather it should be used in impossible cases (like array index is out of bounds in C)
Read this post for more.
One method which I used to great effect is the one used by W. Richard Stevens in Unix Network Programming (code is downloadable here. For common functions which he expects to succeed all the time, and has no recourse for a failure, he wraps them, using a capital letter (code compressed vertically):
void * Malloc(size_t size) {
void *ptr;
if ( (ptr = malloc(size)) == NULL)
err_sys("malloc error");
return(ptr);
}
err_sys here displays the error and then performs an exit(1). This way you can just call Malloc and know that it will error out if there is a problem.
UNP continues to be the only book I've where I think the author has code which checks the return values of all the functions which it's possible to fail. Every other book says "you should check the return values, but we'll leave that for you to do later".
I tend to
Delegate error checking to wrapper functions (like Stevens)
On error, simulate exceptions using longjmp. (I actually use Dave Hanson's C Interfaces and Implementations to simulate exceptions.)
Another option is to use Don Knuth's literate programming to manage the error-handling code, or some other kind of preprocessor. This option is available only if you get to set the rules for your shop :-)
The only grouping property of code like this is that there simply is an externally imposed sequence that it has to follow. This is why you put these allocations into one function, but this is a very weak commonality. Why some people recommend to abandon the scope advantages of nested if's is beyond my understanding. You are effectively trying to put lipstick on a pig (no insult intended) - the code's nature will never yield anything clean, the best you can do is to use the compilers help to catch (maintenance) errors. Stick with the if's IMHO.
PS: if I haven't convinced you yet: what will the goto-solution look like if you have to take ternary decisions? The if's will get uglier for sure, but the goto's???

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