• 0

[C++] Coding style of const local variables


Question

I've been wondering about this recently (and haven't been able to find any good resources online).

Would you make local variables that should not (or do not) change const?

From following several other projects they always seem to leave them non-const.

But I thought it is a fairly good documentation tool to make them const, although it does clutter up the code somewhat, especially if you have something like "int const * p;".

This is more of a style question, so I don't care if there are or are not any performance improvements.

22 answers to this question

Recommended Posts

  • 0

As far as an online resource: stackoverflow.com. All the gurus and professional developers answer questions there. I wouldn't be where I was if it wasn't for them. I've done very little C++ but that's because I'm caught up with PHP at this point in time...

I would like to try to answer your question but I recommend you visit the link instead if you'd like to get a thorough answer.

  • 0
  On 09/04/2011 at 13:56, Lant said:

Would you make local variables that should not (or do not) change const?

If a value does not change, then I usually declare it as a static const or a preprocessor symbol. If the variable should not change because of program logic, for instance, passing a variable to a function that doesn't have permission to change it, then a simple constant qualifier is sufficient.

  On 09/04/2011 at 13:56, Lant said:

From following several other projects they always seem to leave them non-const.

But I thought it is a fairly good documentation tool to make them const, although it does clutter up the code somewhat, especially if you have something like "int const * p;".

It certainly makes code more readable, manageable, and helps to isolate logic and behavioural errors.

  On 09/04/2011 at 13:56, Lant said:

This is more of a style question, so I don't care if there are or are not any performance improvements.

It's not merely a question of style. because a constant qualifier determines how a variable can be used. It's also self documenting, prevents unexpected behaviour, and allows the compiler to perform additional optimisations.

  • 0
  On 09/04/2011 at 13:59, surrealvortex said:

No point really. I would rather include a clear comment indicating that the value should not change.

Yes, but why include a comment when it can be ignored later on when you can add a const that will be enforced by the compiler?

  • 0
  On 09/04/2011 at 14:12, Flawed said:

If a value does not change, then I usually declare it as a static const or a preprocessor symbol. If the variable should not change because of program logic, for instance, passing a variable to a function that doesn't have permission to change it, then a simple constant qualifier is sufficient.

I'm talking about local variables inside functions here, not class level or global constants.

Plenty of my code is like the following:


bool x(C c)
{
std::vector<int> v = c.fn();
int i = c.fn2();


if ( std::find(v.begin(), v.end(), i) != v.end() )
...

return ;
}
[/CODE]

If v and i was never going to be modified by the rest of the function should I make them const?

Edited by Lant
  • 0
  On 09/04/2011 at 13:59, surrealvortex said:

No point really. I would rather include a clear comment indicating that the value should not change.

And permit behaviour that defies the design of the program? You're inviting problems if you follow that path. Let the code document itself, and at the same time prevent unexpected behaviour; it's far easier to debug and certify your application this way.

  • 0
  On 09/04/2011 at 14:19, Lant said:

I'm talking about local variables inside functions here, not class level or global constants.

Plenty of my code is like the following:


bool x(C c)
{
std::vector<int> v = c.fn();
int i = c.fn2();


if ( std::find(v.begin(), v.end(), i) != v.end() )
...

return ;
}
[/CODE]

If v and i was never going to be modified by the rest of the function should I make them const?

For instance in boost\date_time\src\gregorian\greg_month.cpp

[CODE]
special_values special_value_from_string(const std::string& s) {
short i = date_time::find_match(special_value_names,
special_value_names,
date_time::NumSpecialValues,
s);
if(i >= date_time::NumSpecialValues) { // match not found
return not_special;
}
else {
return static_cast<special_values>(i);
}
}
[/CODE]

The i is never changed, but it is not declared const.

This is from boost sources, and they use fairly up-to-date coding methods and styles.

So why don't they do it?

[b]I don't think in that example i is a constant. Simple as that.[/b]

Imagine if they call date_time::find_match() again within the program. If the i variable was a constant and date_time::find_match() returned a different value, the i variable would change and the program would throw a runtime error

Also, from: Stackoverflow.com

  Quote

In general, I think it's always a good idea to make your intentions clear this way, for a number of reasons:

It's easier to understand what you meant when you wrote it.

It's easier for others to reason about your code when they read it.

It's easier for the compiler to make inferences about what you want to do.

It's easier for the compiler to prevent logical errors.

Making variables constant is a perfectly legitimate way to accomplish all of the above, in the specific case of intending "I don't want this variable to change its value".

(This is why I love stack overflow, they just find the right words to explain which I'm bad at) :)

In short, it is strongly suggested you make the int a constant if the integer will not change throughout the program.

  • 0
  On 09/04/2011 at 14:19, Lant said:

I'm talking about local variables inside functions here, not class level or global constants.

Plenty of my code is like the following:


bool x(C c)
{
std::vector<int> v = c.fn();
int i = c.fn2();


if ( std::find(v.begin(), v.end(), i) != v.end() )
...

return ;
}
[/CODE]

If v and i was never going to be modified by the rest of the function should I make them const?

Why not write it as:

[CODE]
bool x(C c)
{
std::vector<int> v = c.fn();
if ( std::find(v.begin(), v.end(), c.fn2()) != v.end() )
...

return ;
}
[/CODE]

But if you insist on doing it that way, no I don't see a need to define it as a constant in the function. The const qualifier is most beneficial when two modules are interacting, or to prevent some unexpected behaviour. Use of it in a local function as in your example is unnecessary. There are cases though where you might want to define a static local constant for a function; for instance, in order to encapsulate/hide the details of it if it's specific to that function, or perhaps if a function returns a constant pointer, but for simple temporary values on the stack, there isn't much point.

  • 0
  On 09/04/2011 at 14:34, Flawed said:

Why not write it as:


bool x(C c)
{
std::vector<int> v = c.fn();
if ( std::find(v.begin(), v.end(), c.fn2()) != v.end() )
...

return ;
}
[/CODE]

But if you insist on doing it that way, no I don't see a need to define it as a constant in the function. The const qualifier is most beneficial when two modules are interacting, or to prevent some unexpected behaviour. Use of it in a local function as in your example is unnecessary. There are cases though where you might want to define a static local constant for a function; for instance, in order to encapsulate/hide the details of it if it's specific to that function, or perhaps if a function returns a constant pointer, but for simple temporary values on the stack, there isn't much point.

I disagree with this. For the same reasons I had posted in my reply above Flawed's post.

  • 0
  On 09/04/2011 at 14:25, Tekkerson said:

I don't think in that example i is a constant. Simple as that.

Imagine if they call date_time::find_match() again within the program. If the i variable was a constant and date_time::find_match() returned a different value, the i variable would change and the program would throw a runtime error

It could be declared "const short i" and it would all be perfectly fine until the static_cast which would probably cause a compile error as the cast is trying to remove constness. (I realised it was a bad example so I removed it)

But it wouldn't throw a runtime error.

  • 0
  On 09/04/2011 at 14:25, Tekkerson said:

In short, it is strongly suggested you make the int a constant if the integer will not change throughout the program.

I agree with "throughout the program", or even:

void my_func() {
static const int my_func_number = 12345;
/* do some work */
}

But for temporary local function variables, I don't really see a justification in general, and certainly not in the example code provided by the OP.

  • 0
  On 09/04/2011 at 14:44, Lant said:

It could be declared "const short i" and it would all be perfectly fine until the static_cast which would probably cause a compile error as the cast is trying to remove constness. (I realised it was a bad example so I removed it)

But it wouldn't throw a runtime error.

You know, that's funny at first I typed compile then I edited it to runtime... (thought processes got mixed up or something)

  • 0
  On 09/04/2011 at 14:45, Flawed said:

I agree with "throughout the program", or even:

void my_func() {
static const int my_func_number = 12345;
/* do some work */
}

But for temporary local function variables, I don't really see a justification in general, and certainly not in the example code provided by the OP.

If it's a constant, it should always be declared constant no matter where it is. What if for some reason you changed something in the code that made the variable change when it wasn't supposed to? It's just a good coding practice. But that's for the OP to decide.

  • 0
  On 09/04/2011 at 14:41, Tekkerson said:

I disagree with this. For the same reasons I had posted in my reply above Flawed's post.

That was talking in general, and I do agree with those principles as can be seen by my original post, but in general, temporary local function variables aren't likely to be const targets.

Edit: Removed my unnecessary sarcasm.

  • 0

My code is already littered with BOOST_STATIC_CONSTANTs,

what I was really after is if the documentation value of declaring local variables (mostly stl containers) const is worth it over the readability loss of adding const.

I suppose its just one of those things in C++ that there is no real answer either way

  • 0
  On 09/04/2011 at 14:53, Tekkerson said:

If it's a constant, it should always be declared constant no matter where it is. What if for some reason you changed something in the code that made the variable change when it wasn't supposed to? It's just a good coding practice. But that's for the OP to decide.

I agree in general with your logic, but you have to ask the question, why is that variable a constant? We are speculating without knowing the actual case. At first glance, I wouldn't declare it as a constant, but that's just me. Perhaps you are right.

  • 0
  On 09/04/2011 at 14:57, Flawed said:

That was talking in general, and I do agree with those principles as can be seen by my original post, but in general, temporary local function variables aren't likely to be const targets.

I do have another thing to add though. Even with Flawed's point, even in the smallest cases I just think it's a good habit to do it where it applies, Lant.

Though, in the end I think this is more of a personal question. It boils down to:

Would you prefer cleanliness/convenience (less declarations) over "correctness" (which also has it's benefits)? Which is what I think sums up both me and Flawed's point.

Edit: To fit with Flawed's edits. :p

  • 0
  On 09/04/2011 at 14:58, Lant said:

My code is already littered with BOOST_STATIC_CONSTANTs,

what I was really after is if the documentation value of declaring local variables (mostly stl containers) const is worth it over the readability loss of adding const.

I suppose its just one of those things in C++ that there is no real answer either way

It's the same in C as well. While I agree with most of what Tekkerson's said, in practise, I rarely use const qualifiers in my own code in temporary local function variables. The occasions when I do are, if I want to declare a static const value to be used only for that function only, or if another function returns a pointer value that is immutable.

Though now I think about it, Tekkerson's arguments are compelling. So if you find it makes your code more readable, manageable, and prevents program logic / behavioural errors, then go for it.

  • 0

I only use const where the language forces me to, for example:

void myFunction(const std::string&amp; arg); // const must be used to allow the following usage:
myFunction("String literal");

Having successfully developed applications in Python, where there is no equivalent of the C++ const keyword, I don't believe const adds enough value to be worth having to constantly (no pun intended) worry about it. I just put constants in ALL_CAPS and I never declare const methods.

  • 0
  On 09/04/2011 at 14:22, Flawed said:

And permit behaviour that defies the design of the program? You're inviting problems if you follow that path. Let the code document itself, and at the same time prevent unexpected behaviour; it's far easier to debug and certify your application this way.

Const variables can be modified indirectly. It is not foolproof.

I can see where you are coming from. The code definitely will document itself that way, but when I suggested adding a comment, I meant a detailed comment explaining the intention. Not something like: /*This is a const*/

  • 0
  On 09/04/2011 at 18:17, surrealvortex said:

Const variables can be modified indirectly. It is not foolproof.

I can see where you are coming from. The code definitely will document itself that way, but when I suggested adding a comment, I meant a detailed comment explaining the intention. Not something like: /*This is a const*/

I would discard what I said there. I misunderstood the original question, and that comment was aimed at function parameters and class/global scope variables. Nevertheless, I agree with what you are saying. A terse comment can help explain the variable's purpose and/or why it's immutable if it's not already self explanatory. Personally, I haven't really felt the need to use constant qualifiers at the function scope level except in the special circumstances I outlined previously, but I suppose as long as the code is readily readable, then either way would work.

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

    • No registered users viewing this page.
  • Posts

    • I suspect this was primarily developed with the Switch 2 in mind, which would explain the poor visuals. It seems like they're hoping the nostalgic GoldenEye 64 crowd is still loyal to Nintendo consoles. Unfortunately, this might be yet another title limited by development for underpowered Nintendo hardware.
    • Amazon's Lab126 ventures into "Physical AI" with new robotics team by Paul Hill Amazon has announced that it’s forming a new agentic AI team within its secretive hard research and development division, Lab126, to begin work on physical AI. Specifically, the company is looking to develop an agentic AI framework for use in robotics, which could start to impact blue-collar jobs, especially at its warehouses. Agentic AI is one of the latest developments in AI, superseding the previous generative AI that took off with the launch of ChatGPT. Agentic AI models are special because they can complete multi-step actions for the user to complete complex tasks. Thanks to all the visual and audio capabilities added to generative AI in previous years, these agentic models can perceive their environment, reason, plan, and act to achieve goals with minimal human intervention. If Amazon can successfully bring agentic AI to robots, they will finally be able to interact with the real world in a way they can’t today, as software running on a computer. Many people are concerned about AI’s impact on white-collar jobs right now, but when Amazon develops physical AI, it will also affect blue-collar manual work. The work is going to be carried out by Amazon’s R&D company, Lab126. It was set up over 20 years ago and has created many iconic Amazon devices, including the Kindle, Fire tablets, Amazon Fire TV, Amazon Echo devices, and more. Who it affects, and how The biggest impact of physical AI developed by Lab126 will be on Amazon’s warehouses and logistics. The company said it wants to create robots that can perform tasks based on natural language instructions. As usual for a big tech company, Amazon claims that these robots will be assistants, but it’s difficult to see how they won’t reduce the need for people. Solely based on Amazon’s plans to automate work in its factories, customers will see an indirect impact from the move through faster deliveries and potentially lower costs. The decision by Amazon to focus on agentic AI in robots is pretty interesting because so far, we’ve mainly been hearing about agentic AI limited to computer applications, such as intelligent web browsers like Opera Neon. Why it's happening Amazon has a reputation for being an efficient company, particularly when it comes to the employment of warehouse workers who are known to have strict restroom breaks. Creating robots that can help speed up warehouse activities will further boost efficiency at the company and could potentially reduce its costs and improve safety. The beginning of work on physical AI is just the next evolution of AI that we could start to hear about in the coming months and years. As agentic AI gets better, companies will be looking to see what they can advance next and physical AI may be where they choose to go next; it certainly seems like this is what Amazon has settled on in this move. If Amazon’s physical AI doesn’t lead to mass layoffs of warehouse employees, it could drastically boost worker safety. Employees could potentially be less fatigued from moving around so much, which could lead to better concentration and fewer accidents. Right now, Amazon claims that these robots will only be assistants and not replacements. While Amazon will certainly be a leader in physical AI, given its massive wealth to throw at the problem, once the technology is available, it will likely be available for sale to other businesses to use, too. Caveats and what to watch for While it’s a notable development, it still sounds like Amazon is in the early stages of developing these physical AI systems, given that it has only just set up the team. We also don’t know what specific products Amazon is planning to build or the timelines for deployment. Ever since generative AI came onto the scene, there has been discussion of AI safety. With AI moving into the physical world, it will also bring up discussion about the safety concerns. Current measures are mainly concerned with AI software running on computers, not when it interacts physically with the world. Finally, and probably the biggest concern, what will these “assistants” do to people’s jobs? Companies will likely find themselves bringing in fewer new hires initially, but it could also displace people from their jobs. Source: CNBC
    • Nintendo Switch 2 launches, where to buy and a list of games that it may not support by Sayan Sen Nintendo announced the Switch 2 back in early April this year and then followed that up with more details related to performance and hardware features later. The company touted 10x the performance of the Switch. However, on the flip side, the battery suffers, and you also need new microSD Express cards for storage. For those who need a refresher, here are the technical specification details of the Switch 2: Specification Details Dimensions Approx. 166mm x 272mm x 13.9mm (with Joy-Con 2 attached); Maximum thickness from control stick tip to ZL/ZR buttons: 30.7mm Weight Approx. 401g (console only); Approx. 534g (with Joy-Con 2 controllers attached) Screen 7.9-inch capacitive touch LCD; 1920x1080 resolution; HDR10 support; VRR up to 120 Hz CPU/GPU Custom processor made by NVIDIA Storage 256 GB UFS (a portion reserved for system use) Communication Wireless LAN (Wi‑Fi 6), Bluetooth; Wired LAN available in TV mode via dock Video Output Up to 3840x2160 at 60 fps via HDMI in TV mode; Supports 120 fps at lower resolutions; HDR10 enabled Audio Output Linear PCM 5.1 channel via HDMI; Stereo speakers Microphone Built-in monaural microphone with noise cancellation, echo cancellation and auto gain control Buttons POWER and Volume buttons USB Ports 2 USB Type-C ports (bottom port for charging/dock connection; top port for accessories/charging) Audio Jack 3.5mm stereo mini plug (CTIA standard) Game Card Slot Supports both Nintendo Switch 2 and Nintendo Switch game cards Expansion Slot microSD Express card slot (compatible with cards up to 2 TB; other microSD cards can copy screenshots and videos) Sensors Accelerometer, gyroscope, brightness sensor Battery Lithium-ion, 5220 mAh; Approx. 2–6.5 hours lifetime; 3-hour charge time in sleep mode Dock Approx. 115mm x 201mm x 51.2mm; Weight: approx. 383g For those looking to get one, major retailers like Walmart, GameStop, Best Buy, and Target have all confirmed that they will have limited console stock from time to time so you will need to be on alert and check back. Nintendo has also published a full list of games that may not work on the Switch 2: Borderlands 3 Chrono Cross: The Radical Dreamers Edition Crash Bandicoot N-Sane Trilogy Guilty Gear XX Accent Core Plus R KarmaZoo Marvel vs. Capcom Fighting Collection: Arcade Classics Mortal Kombat 1 Overwatch 2 Star Wars: Knights of the Old Republic II: The Sith Lords Star Wars Republic Commando Super Mega Baseball 4 Tombi! Special Edition Tony Hawk's Pro Skater 1+2 Touhou Genso Wanderer Reloaded Ty the Tasmanian Tiger HD Warriors: Abyss However, keep in mind that Nintendo last updated the support list last month on May 27th and the company may still be testing these. So keep an eye on the official list of games on this webpage here on Nintendo's site. Have you managed to pick up the Nintendo Switch 2? Let us know in the comments.
    • Court orders Apple to keep web links in the App Store, eroding its iOS payment monopoly by Fiza Ali Apple has been ordered to continue permitting web links and external payment options in the App Store after its bid to halt court’s ruling was declined today by a higher court. Earlier this year, in April, a federal judge decreed that Apple must allow developers to include web links in their iOS apps, remove restrictions on link formatting, and enable external payment methods without taking a commission on transactions. Apple immediately appealed and sought an injunction to delay implementation of the order while the case progressed. However, the United States Court of Appeals has now refused Apple’s emergency request to stay the district court’s order. In its decision, the panel held that Apple had not demonstrated a sufficient likelihood of success on appeal, nor that it would suffer irreparable harm if the order were enforced. The court also considered potential prejudice to other parties and the public interest, concluding that an immediate suspension was not warranted. This ruling makes it much harder for Apple to overturn the April decision, which came from a lawsuit initiated by Epic Games. Epic first sued Apple’s App Store policies in 2020, claiming that the company’s restrictions harmed competition. While Epic did not prevail on every count, the court did rule that Apple must allow developers to inform users of alternative purchasing options at better prices. Despite that narrow victory, Apple repeatedly failed to conform to the terms from the original 2021 ruling, prompting the judge in April to issue a more detailed order outlining precisely how the App Store must be “opened up”. In response to the April ruling, prominent third-party apps have swiftly implemented web-based purchasing links. Both Spotify and Amazon’s Kindle app now include buttons directing users to purchase subscriptions via their websites, bypassing Apple’s in-app payments. Additionally, Fortnite has made a comeback on iOS after around five years, presenting users with the choice between Apple’s in-app payment system and Epic’s own payment and rewards mechanism. According to Epic CEO Tim Sweeney, there is presently a 60:40 split in usage favouring Apple’s system over Epic’s, though the gap appears to be narrowing. An Apple spokesperson, Olivia Dalton, issued a statement expressing the company’s disappointment: For now, Apple must comply with the existing injunction. Unless the Appeals Court later overturns the ruling, developers can continue to include web payment links, and Apple’s longstanding monopoly over iOS payment processing may continue to erode. The ultimate resolution will depend on the outcome of the ongoing appeals, which could set a significant precedent for how app marketplaces operate in the future. Source: The Verge
  • Recent Achievements

    • Rookie
      GTRoberts went up a rank
      Rookie
    • First Post
      James courage Tabla earned a badge
      First Post
    • Reacting Well
      James courage Tabla earned a badge
      Reacting Well
    • Apprentice
      DarkShrunken went up a rank
      Apprentice
    • Dedicated
      CHUNWEI earned a badge
      Dedicated
  • Popular Contributors

    1. 1
      +primortal
      397
    2. 2
      +FloatingFatMan
      177
    3. 3
      snowy owl
      170
    4. 4
      ATLien_0
      167
    5. 5
      Xenon
      134
  • Tell a friend

    Love Neowin? Tell a friend!