• 0

Curly braces placement and indentation


Question

Almost all the code I've seen until now uses the following style for curly braces:

void swap(int &a, int &b)
{
	int temp = a;
	a = b;
	b = temp;
}

Visual Studio also defaults to this. However I have read Code Complete 2nd edition and Steve McConnell argues against this style. "Avoid unindented being-end pairs (...) Although this approach looks fine, it (...) doesn't show the logical structure of the code. Used this way, the begin and end aren't part of the control construct, but they aren't part of the statements after it either." Steve McConnell recommends using the pure block style, which emulates Visual Basic (where there's no curly braces):

void swap(int &a, int &b) {
	int temp = a;
	a = b;
	b = temp;
}

or this (begin-end block boundaries):

void swap(int &a, int &b) 
	{
	int temp = a;
	a = b;
	b = temp;
	}

Although I tend to agree with McConnell's reasoning, all the books I read, the classes I attended, and Visual Studio, use the first style, so I find it a bit weird. What do you think?

Recommended Posts

  • 0
Also, there are different variations when it comes to case statements:

switch (item)
{
	case 0:
		code0;
	break;

	case 1:
		code1;
		break;
}

Notice how the break statements are in different places? Also, when you create variables in case statements, braces are required (at least in C/C++). In that case, does the break statement go inside or outside of the braces? *sigh* Too many conventions! :D

Personally I find it stupid to have to add the break statement after each case. In languages derived from BASIC, such as VB.NET, that doesn't exist and it's more logical. IMO, what would be logical in C-based languages is to have each case enclosed in curly braces.
  • 0
Personally I find it stupid to have to add the break statement after each case. In languages derived from BASIC, such as VB.NET, that doesn't exist and it's more logical. IMO, what would be logical in C-based languages is to have each case enclosed in curly braces.

I tend to put all my switch(..) cases within there own braces. makes it easier to see grouped statements.

  • 0
Personally I find it stupid to have to add the break statement after each case. In languages derived from BASIC, such as VB.NET, that doesn't exist and it's more logical. IMO, what would be logical in C-based languages is to have each case enclosed in curly braces.

The benefit of the break; statement is that is gives C/C++ (Not C# for whatever reason) the ability to fall from one case to another. For example:

int myVar = 0;
cin >> myVar;

switch(myVar)
{
    case 0:
        MyFunc();
        break;
    case 1:
        Foo();
    case 2:
        Bar();
        break;
}

If the user inputs 0, then MyFunc is executed, if the user inputs 1, then Foo AND Bar are executed, and if the user inputs 2, then only Bar is executed. This is very useful in certain situations, especially when cases are very similar, but not identical.

  • 0
The benefit of the break; statement is that is gives C/C++ (Not C# for whatever reason) the ability to fall from one case to another. For example:

int myVar = 0;
cin >> myVar;

switch(myVar)
{
    case 0:
        MyFunc();
        break;
    case 1:
        Foo();
    case 2:
        Bar();
        break;
}

If the user inputs 0, then MyFunc is executed, if the user inputs 1, then Foo AND Bar are executed, and if the user inputs 2, then only Bar is executed. This is very useful in certain situations, especially when cases are very similar, but not identical.

That's true, but I don't see why you just can't do:

Foo();

Bar();

Achieves the same functionality. Also, for people saying style 2 minimizes the number of lines...is there a reason you guys are trying to cut down on line count?

  • 0

I use the 1st style, but i can deal with the 2nd style in most cases. The problem i run into is when you have multi-line starters for the blocks, such as:

if ( myReallyLongObjectName.MyReallyLongFunctionNameOne() &&
	 myReallyLongObjectName.MyReallyLongFunctionNameOne() &&
	 myReallyLongObjectName.MyReallyLongFunctionNameOne() &&
	 myReallyLongObjectName.MyReallyLongFunctionNameOne() ) 
{

	 MyInsideFunctionCall();

}

if ( myReallyLongObjectName.MyReallyLongFunctionNameOne() &&
	 myReallyLongObjectName.MyReallyLongFunctionNameOne() &&
	 myReallyLongObjectName.MyReallyLongFunctionNameOne() &&
	 myReallyLongObjectName.MyReallyLongFunctionNameOne() ) {

	 MyInsideFunctionCall();

}

I feel like the 1st way (And 1st style) more clearly separates the inside of the if-block from the conditions. In the 2nd style, you pretty much have to just look for the whitespace, which seems pretty improper (esp. considering it may not even be there!)

  • 0
That's true, but I don't see why you just can't do:

Foo();

Bar();

Achieves the same functionality. Also, for people saying style 2 minimizes the number of lines...is there a reason you guys are trying to cut down on line count?

True, but if you've got (for example) 20 case statements that all have common code, then it is easier to maintain the code if the common code is only written once. For example, if you've got 20 lines of common code between 5 case statements, you've got the same code written 5 times, which means it takes 5x longer to maintain should you need to adjust something in the common code as well as the code added by the other cases, whereas if you're case statements fall through, you decrease line count and make your code more maintainable.

I think (but don't hold me to this, it's a long time since I've studies low level) that repeating code also uses more memory when running the executable, as the program needs to store more instructions, negligible in the modern day? yes, but it's a slippery slope.

That said though, there is less risk of error through not falling through cases. I can't count the amount of times I've left a break; statement out with disastrous consequences! :laugh:

  • 0
Personally I find it stupid to have to add the break statement after each case. In languages derived from BASIC, such as VB.NET, that doesn't exist and it's more logical. IMO, what would be logical in C-based languages is to have each case enclosed in curly braces.

The reason for the break statement is because C allows a fall-through behavior, which is similar to specifying multiple values to match a single case in VB:

Select Case variable
  Case 1, 3, 5, 7, 9
	Debug.WriteLine("Your number was odd!")
  Case 0, 2, 4, 6, 8
	Debug.WriteLine("Your number was even!")
  Case Else
	Debug.WriteLine("Your number wasn't between 0 and 9 inclusive!")
End Select

C/C++:

switch (variable)
  {
	case 1:
	case 3:
	case 5:
	case 7:
	case 9:
	  puts("Your number was odd!");
	break;

	case 0:
	case 2:
	case 4:
	case 6:
	case 8:
	  puts("Your number was even!");
	break;

	default:
	  puts("Your number wasn't between 0 and 9 inclusive!");
  }

Why isn't there a break statement after the default case? I could ask something similar about BASIC - why isn't there an End Case statement?

While the example is rather ridiculous, especially since you can use a remainder operator on the switch/Select Case parameter to end up with fewer cases to test in this specific example, it does illustrate a similarity. I suppose a mathematical set notation could have been used in C to make it more BASIC-like (it would be a new array, basically), but that isn't the way C works.

The idea regarding using braces to denote the beginnings and endings of case statements in C isn't a bad idea:

switch (variable)
  {
	case 0:
	case 2:
	  {
		//code
	  }

	default:
	  {
		//code
	  }
  }

So the suggestion made about using braces to denote the beginnings and endings of cases could work while still allowing the fall-through mechanism. Doing such a thing would make parsing the code a bit harder.

Part of the reason the break statement is so useful in this case is because of the fact that it is easier to NOT check for an ending delimiter. The break statement isn't actually the end of a case. The end of a case is undelimited. The break statement is simply used to exit the switch statement. ^_^

However, I personally prefer Python over any other programming language (except for Web programming, where I use PHP).

  • 0

There's nothing stopping you putting additional braces into C or C++ code. In fact, this can be a very good thing, as the compiler can make some very nice code adjustments for you because you're explicitly telling it that certain variables are only used in smaller blocks, thus it may be able to keep that variable inside a register or whatever for a little performance boost.

Likewise, there's nothing stopping you from using braces in a switch statement, in fact sometimes I just do this for the sake of readability.

You do have to be careful, though, too many braces and you'll find yourself scrolling to the right of your code, which is a very bad thing.

Anyway, on topic, I use the first method of braces. To me, it makes a lot more sense, it makes the code more readable and explicitly shows the flow and scope of the code. Some people complain about the lack of vertical screen space, but in this day and age with your high-resolution, 24" wide-screen monitors, it's not really an issue. Plus due to my eyesight, I have to keep the font up pretty high anyway, so loosing an extra line isn't going to make much difference.

Each to their own, though, anything thing to remember is that if you're working in groups, forget about what you do, do what everyone else does as consistent code is better than inconsistent code with tiny bits of consistency that you can read.

  • 0

I actually switched from the second style to the first style recently. I find it much more readable EXCEPT for if/else statements. I much prefer having the opening brace on the same line as the last conditional statement as it implies a link between each branch in a conditional statement set. But it's not that big of a deal.

The third style is just funky, and there are a few other styles I have run into. One type was a variation on #3:

languageStructure()
	  {
			   statement1;
			   statement2;
	  }

To me it seems like a complete waste of keystrokes and whitespace.

I see a lot of the second style in C and C++ code due to its connection with the original K&R C. It is all personal preference though. Use whatever suits you best or your team is using.

  • 0

For if/else statements, I just do this:

if (TRUE == blah)
{
   // Other stuff
}
else
{
   // Some stuff
}

I can see what you mean about if-elseif statements, that CAN get a bit untidy but usually if I have to have an ifelse statement, I'll try to use a switch instead as it's no slower than a bunch of if statements and looks much neater.

  • 0

I like using the second style because it's more compact and i find it eaier to read. That's the way i was taught and i like it because it doesn't waste any lines.

Although at work i've been told to use the first style because it's easier for other people to see the braces. However, for JS we use the second method in case of any semi-colon injection after the first line.

Either way, I use a text editor which highlights the matching braces so i don't have any problems with not seeing the braces properly.

This topic is now closed to further replies.
  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Posts

    • Now 8GB of ram looks even worse in the Neo. I'm so happy I purchased 128GB of DDR 4 when I did.... paid $174. Upgraded my parents laptop to 32GB around the same time for $48. Luckily I have a TON of spare laptops. So i'm good on laptops for a while. I also have a lot of desktops too that I could use if i had to. Lets just hope nothing happens to my main 4 monitor couch workstation.
    • I will keep my current devices for several years... no planning in upgrading until these devices stop working. Too pricey.
    • Apple raises MacBook and iPad prices as memory costs surge by Karthik Mudaliar Apple has raised the U.S. prices of several MacBook and iPad models, including the MacBook Neo, which it launched for $599 less than four months ago. The company’s cheapest laptop now starts at $699, while some MacBook Pro configurations have increased by $300. The changes affect the MacBook Neo, MacBook Air, MacBook Pro, iPad Air, and iPad Pro. Apple has not changed the hardware or storage included with these models, so customers are simply paying more for the same configurations. Here is how the new US pricing compares with the previous starting prices: Product Previous price New price Increase MacBook Neo $599 $699 $100 13-inch MacBook Air, 512GB $1,099 $1,299 $200 14-inch MacBook Pro, 1TB $1,699 $1,999 $300 16-inch MacBook Pro $2,699 $2,999 $300 11-inch iPad Air, 128GB $599 $749 $150 13-inch iPad Air, 128GB $799 $949 $150 11-inch iPad Pro, 256GB $999 $1,199 $200 13-inch iPad Pro, 256GB $1,299 $1,499 $200 The updated prices are already appearing on Apple’s U.S. online store. The MacBook Neo increase will probably attract the most attention. Apple introduced the laptop in March for $599, pitching it as a more affordable Mac for students and buyers considering Windows laptops or Chromebooks. It uses an A18 Pro processor and originally undercut Dell’s new $699 XPS 13 by $100. Following the increase, the two laptops now have the same starting price. The M5 MacBook Air has also lost the price Apple promoted when it launched in March. The 13-inch model arrived with 512GB of storage for $1,099, while Apple’s store now lists the MacBook Air range as starting at $1,299. The 14-inch MacBook Pro with an M5 chip and 1TB of storage has gone from $1,699 to $1,999. Apple has made similar changes to its iPads. The recently released M4 iPad Air, which launched at the same $599 starting price as its predecessor, now starts at $749 for the 11-inch version. The 13-inch version has risen from $799 to $949. The iPad Pro increases are larger in dollar terms. Apple’s 11-inch M5 iPad Pro now starts at $1,199, up from $999, while the 13-inch version has moved from $1,299 to $1,499. Both base models still include 256GB of storage. Apple blamed the increases on the rapidly rising cost of DRAM and NAND flash, which provide system memory and device storage. The company told Reuters that it had tried to shield customers from the increases but could no longer absorb them. “We have never seen a component price increase this much, this quickly,” Apple said. Tim Cook had already warned that price increases were coming. Cook said Apple’s existing component inventory had softened the immediate impact, but that higher memory costs would increasingly affect the company after the June quarter. Much of the pressure comes from the construction of AI data centers. Memory manufacturers are directing more production toward high-margin server products, leaving PC, tablet, and smartphone makers competing for the remaining supply. Apple has not said whether the new prices are temporary or whether further increases are planned. For now, the changes show that even Apple’s purchasing power has not been enough to keep the AI-driven memory shortage away from consumer devices.
    • Ventoy 1.1.16 is out.
    • This is a none story - these low volume Chinese models will always get new experimental features first because Apple and Samsung can't produce them in huge volume to meet demand.
  • Recent Achievements

    • First Post
      kinowa earned a badge
      First Post
    • Rookie
      krychek57 went up a rank
      Rookie
    • Grand Master
      Jaybonaut went up a rank
      Grand Master
    • One Year In
      Philsl earned a badge
      One Year In
    • Dedicated
      Scoobystu earned a badge
      Dedicated
  • Popular Contributors

    1. 1
      +primortal
      462
    2. 2
      +Edouard
      171
    3. 3
      PsYcHoKiLLa
      135
    4. 4
      Michael Scrip
      77
    5. 5
      Xenon
      77
  • Tell a friend

    Love Neowin? Tell a friend!