• 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

    • Microsoft adds reusable skills and finance data connectors to Copilot in Excel by Karthik Mudaliar Microsoft is giving Copilot in Excel a collection of new features aimed squarely at finance teams. The update introduces reusable instructions for common tasks, connections to services such as FactSet and Morningstar, and a better way to review what Copilot intends to do before it starts changing a workbook. The most interesting addition is 'Skills' finally coming to Copilot in Excel. Skills let companies teach Copilot how to handle a recurring process, so employees do not need to write the same detailed prompt every month. Users can create skills that can specify the steps Copilot should follow, along with the required layout, formulas, and formatting. Microsoft says users can create their own skills by saving a SKILL.md file in OneDrive. The file is written using Markdown and tells Copilot when and how to perform the task. Once it is available, a user can select the skill in the Copilot pane or mention it in a prompt using the @ symbol. There is also a library of prebuilt finance skills for customers who do not want to create their own. Microsoft plans to let developers distribute additional skills through the Microsoft Marketplace and the Microsoft 365 Admin Center, with LSEG, Ramp, Rogo, samaya.ai, Velixo, and Vena among the first partners involved. The company says that it is also expanding the external data that Copilot can access from inside Excel. New connectors are being added for CB Insights, Daloopa, FactSet, Morningstar, PitchBook, and S&P Global data through technology developed by Kensho. There is a catch, however. Accessing these services may require a separate subscription from the relevant data provider, so a Microsoft 365 Copilot licence will not necessarily unlock all of them. FactSet is also only available in preview for now, with general availability planned for July. Microsoft is also trying to make Copilot’s workbook edits easier to inspect. Users can switch to a planning mode that shows which sheets, cell ranges, formulas, and assumptions Copilot intends to work with before it begins making changes. Once the work is complete, the Show Changes pane can distinguish edits made by Copilot from those made by human collaborators. The update continues Microsoft’s push to turn Excel Copilot from a chatbot into an agent that can carry out longer tasks. The company previously added an Agent Mode capable of planning and completing multi-step Excel work. Microsoft also recently acquired financial AI startup Fintool, another indication that finance is becoming a key target for its Excel AI strategy. Prebuilt skills, personalization, workbook rules, external connectors, planning mode, and Copilot attribution in Show Changes are generally available to Microsoft 365 Copilot customers using Excel on the web, Windows, and macOS. Custom skills are initially available to Microsoft 365 Insiders on Windows and Mac starting today. Microsoft plans to make them generally available across Windows, Mac, and the web over the next month. Partner-built skills are expected during the third quarter of the year. Availability may still differ depending on region and licensing.
    • Exactly. They serve different (although related) purposes.
    • Do not enter the code under any circumstances, or you will be sorry. It's definitely and most likely a hacking attempt.  That happened to me a couple of years ago, and I kept receiving those prompts for months. It's simply the attacker trying to get you tired of the constant requests, so you just give up and enter the code, so they can log in to your account. 
  • 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
      438
    2. 2
      +Edouard
      169
    3. 3
      PsYcHoKiLLa
      134
    4. 4
      Xenon
      77
    5. 5
      Michael Scrip
      75
  • Tell a friend

    Love Neowin? Tell a friend!