Policy Update - Rules changes incoming for AI content - Read Here

Viewing last 25 versions of comment by LemonDrop on image #1941318

LemonDrop
Duckinator - Same nonsensical quacks in every pond
Nightmare in the Moon - Had their OC in the 2024 Derpibooru Collab.
Pixel Perfection - I still call her Lightning Bolt
Lunar Guardian - Earned a place among the ranks of the most loyal New Lunar Republic soldiers (April Fools 2023).
Crystal Roseluck - Had their OC in the 2023 Derpibooru Collab.
Elements of Harmony - Had an OC in the 2022 Community Collab
Non-Fungible Trixie -
Twinkling Balloon - Took part in the 2021 community collab.
Ten years of changes - Celebrated the 10th anniversary of MLP:FiM!
My Little Pony - 1992 Edition

C++ Crazed
"[@NotAPseudonym":](/1941318#comment_7828158
)  
If an object can avoid being default constructed it should be. Very few objects I make ever have default constructors for this reason (it's not needed since again it adds overhead to put it in a non-invalid default state to be "safe"). Also your example is still less than ideal imo for various reasons. Firstly, @`a@` and @`b@` can clearly be @`const@` but they miss out on that because they're not being initialized with the data you're setting them to directly (@`a@` is being modified but that should be a for loop anyways to avoid bug prone logic with something as simple as trying to loop for a number of iterations, but really that is more opinion based since a while loop might be your own preference). Additionally, @`d@` can and should be @`const@` and be located in the inner scope for reasons previously mentioned. Const correctness is there to help the program be safer, right now one could accidentally write to any of those variables where in the original intent they were assumed to be constant throughout (after all, these are inputs, they don't appear to need to change at any point), and discontinuities between the programmer's mind and reality are what cause bugs.


 
Personally I'd write it like:


 
unsigned const a{ input\("a"\) };
unsigned const b{ input\("b"\) };
unsigned c{ 1 };

for \(unsigned i{ a }; i != 0; --i\) {
unsigned const d{ i \* b };

output\(d\);

c += d;
}

output\(c\);


 
Your point about temporary objects is valid, constructing expensive objects inside of loops usually isn't a good idea, but neither is assigning them. Remember, copy and move assignment both call a destructor of the old value just the same as it going out of scope or to the next loop iteration, and a constructor will still need to be invoked in the loop body somewhere each iteration since you aren't just whipping up classes out of thin air so it's really no different than if it was initialized as a local instance within the loop scope. In cases like that you may want to redesign your code so that it does not happen, but for integers or other primitive types you won't have issues since they'll be in registers and heavily optimized anyways, the location in scopes and const-ness of them is really just benefiting you for the most part at that point (and perhaps helping the compiler optimize a little better).
No reason given
Edited by LemonDrop
LemonDrop
Duckinator - Same nonsensical quacks in every pond
Nightmare in the Moon - Had their OC in the 2024 Derpibooru Collab.
Pixel Perfection - I still call her Lightning Bolt
Lunar Guardian - Earned a place among the ranks of the most loyal New Lunar Republic soldiers (April Fools 2023).
Crystal Roseluck - Had their OC in the 2023 Derpibooru Collab.
Elements of Harmony - Had an OC in the 2022 Community Collab
Non-Fungible Trixie -
Twinkling Balloon - Took part in the 2021 community collab.
Ten years of changes - Celebrated the 10th anniversary of MLP:FiM!
My Little Pony - 1992 Edition

C++ Crazed
"@NotAPseudonym":/1941318#comment_7828158
If an object can avoid being default constructed it should be. Very few objects I make ever have default constructors for this reason (it's not needed since again it adds overhead to put it in a non-invalid default state to be "safe"). Also your example is still less than ideal imo for various reasons. Firstly, @a@ and @b@ can clearly be @const@ but they miss out on that because they're not being initialized with the data you're setting them to directly (@a@ is being modified but that should be a for loop anyways to avoid bug prone logic with something as simple as trying to loop for a number of iterations, but really that is more opinion based since a while loop might be your own preference). Additionally, @d@ can and should be @const@ and be located in the inner scope for reasons previously mentioned. Const correctness is there to help the program be safer, right now one could accidentally write to any of those variables where in the original intent they were assumed to be constant throughout (after all, these are inputs, they don't appear to need to change at any point), and discontinuities between the programmer's mind and reality are what cause bugs.

Personally I'd write it like:

unsigned const a{ input("a") };
unsigned const b{ input("b") };
unsigned c{ 1 };

for (unsigned i{ a }; i != 0; --i) {
unsigned const d{ i * b };

output(d);

c += d;
}

output(c);

Your point about temporary objects is valid, constructing expensive objects inside of loops usually isn't a good idea, but neither is assigning them. Remember, copy and move assignment both call a destructor of the old value just the same as it going out of scope or to the next loop iteration, and a constructor will still need to be invoked in the loop body somewhere each iteration since you aren't just whipping up classes out of thin air so it's really no different than if it was initialized as a local instance within the loop scope. In cases like that you may want to redesign your code so that it does not happen, but for integers or other primitive types you won't have issues since they'll be in registers and heavily optimized anyways, the location in scopes and const-ness of them is really just benefiting you for the most part at that point (and perhaps helping the compiler optimize a little better).
No reason given
Edited by LemonDrop
LemonDrop
Duckinator - Same nonsensical quacks in every pond
Nightmare in the Moon - Had their OC in the 2024 Derpibooru Collab.
Pixel Perfection - I still call her Lightning Bolt
Lunar Guardian - Earned a place among the ranks of the most loyal New Lunar Republic soldiers (April Fools 2023).
Crystal Roseluck - Had their OC in the 2023 Derpibooru Collab.
Elements of Harmony - Had an OC in the 2022 Community Collab
Non-Fungible Trixie -
Twinkling Balloon - Took part in the 2021 community collab.
Ten years of changes - Celebrated the 10th anniversary of MLP:FiM!
My Little Pony - 1992 Edition

C++ Crazed
"@NotAPseudonym":/1941318#comment_7828158
If an object can avoid being default constructed it should be. Very few objects I make ever have default constructors for this reason (it's not needed since again it adds overhead to put it in a non-invalid default state to be "safe"). Also your example is still bless than ideal imo for various reasons. Firstly, @a@ and @b@ can clearly be @const@ but they miss out on that because they're not being initialized with the data you're setting them to directly (@a@ is being modified but that should be a for loop anyways to avoid bug prone logic with something as simple as trying to loop for a number of iterations). Also ddin thionatlly, case @d@ can and should also be @const@ and be located in the inner scope for reasons previously mentioned. Const correctness is there to help the program be safer, right now one could accidentally write to any of those variables where in the original intent they were assumed to be constant throughout (after all, these are inputs, they don't appear to need to change at any point), and discontinuities between the programmer's mind and reality are what cause bugs.

Your point about temporary objects is valid, constructing expensive objects inside of loops usually isn't a good idea, but neither is assigning them. Remember, copy and move assignment both call a destructor of the old value just the same as it going out of scope or to the next loop iteration, and a constructor will still need to be invoked in the loop body somewhere each iteration since you aren't just whipping up classes out of thin air so it's really no different than if it was initialized as a local instance within the loop scope. In cases like that you may want to redesign your code so that it does not happen, but for integers or other primitive types you won't have issues since they'll be in registers and heavily optimized anyways, the location in scopes and const-ness of them is really just benefiting you for the most part at that point (and perhaps helping the compiler optimize a little better).
No reason given
Edited by LemonDrop
LemonDrop
Duckinator - Same nonsensical quacks in every pond
Nightmare in the Moon - Had their OC in the 2024 Derpibooru Collab.
Pixel Perfection - I still call her Lightning Bolt
Lunar Guardian - Earned a place among the ranks of the most loyal New Lunar Republic soldiers (April Fools 2023).
Crystal Roseluck - Had their OC in the 2023 Derpibooru Collab.
Elements of Harmony - Had an OC in the 2022 Community Collab
Non-Fungible Trixie -
Twinkling Balloon - Took part in the 2021 community collab.
Ten years of changes - Celebrated the 10th anniversary of MLP:FiM!
My Little Pony - 1992 Edition

C++ Crazed
"@NotAPseudonym":/1941318#comment_7828158
If an object can avoid being default constructed it should be. Very few objects I make ever have default constructors for this reason (it's not needed since again it adds overhead to put it in a non-invalid default state to be "safe"). Also your example is still bad, @a@ and @b@ can clearly be @const@ but they miss out on that because they're not being initialized with the data you're setting them to directly (@a@ is being modified but that should be a for loop anyways to avoid bug prone logic with something as simple as trying to loop for a number of iterations). Also in that case @d@ can and should also be @const@ and in the inner scope for reasons previously mentioned. Const correctness is there to help the program be safer, right now one could accidentally write to any of those variables where in the original intent they were assumed to be constant throughout, and discontinuities between the programmer's mind and reality are what cause bugs.

Your point about temporary objects is valid, constructing expensive objects inside of loops usually isn't a good idea, but neither is assigning them. (rRemember, copy and move assignment both call a destructor of the old value just the same as it going out of scope or to the next loop iteration, and a constructor will still need to be invoked in the loop body somewhere each iteration since you aren't just whipping up classes out of thin air) so it's really no different than if it was initialized as a local instance within the loop scope. In cases like that you may want to redesign your code so that it does not happen, but for integers or other primitive types you won't have issues since they'll be in registers and heavily optimized anyways, the location in scopes and const-ness of them is really just benefiting you for the most part at that point (and perhaps helping the compiler optimize a little better).
No reason given
Edited by LemonDrop
LemonDrop
Duckinator - Same nonsensical quacks in every pond
Nightmare in the Moon - Had their OC in the 2024 Derpibooru Collab.
Pixel Perfection - I still call her Lightning Bolt
Lunar Guardian - Earned a place among the ranks of the most loyal New Lunar Republic soldiers (April Fools 2023).
Crystal Roseluck - Had their OC in the 2023 Derpibooru Collab.
Elements of Harmony - Had an OC in the 2022 Community Collab
Non-Fungible Trixie -
Twinkling Balloon - Took part in the 2021 community collab.
Ten years of changes - Celebrated the 10th anniversary of MLP:FiM!
My Little Pony - 1992 Edition

C++ Crazed
"@NotAPseudonym":/1941318#comment_7828158
If an object can avoid being default constructed it should be. Very few objects I make ever have default constructors for this reason (it's not needed since again it adds overhead to put it in a non-invalid default state to be "safe"). Also your example is still bad, @a@ and @b@ can clearly be @const@ but they miss out on that because they're not being initialized with the data you're setting them to directly (@a@ is being modified but that should be a for loop anyways to avoid bug prone logic with something as simple as trying to loop for a number of iterations). Also in that case @d@ can and should also be @const@ and in the inner scope for reasons previously mentioned. Const correctness is there to help the program be safer, right now one could accidentally write to any of those variables where in the original intent they were assumed to be constant throughout, and discontinuities between the programmer's mind and reality are what cause bugs.

Your point about temporary objects is valid, constructing expensive objects inside of loops usually isn't a good idea, but neither is assigning them (remember, copy and move assignment both call a destructor and a constructor still since you aren't just whipping up classes out of thin air). In cases like that you may want to redesign your code so that it does not happen, but for integers or other primitive types you won't have issues since they'll be in registers and heavily optimized anyways, the location in scopes and const-ness of them is really just benefiting you for the most part at that point (and perhaps helping the compiler optimize a little better).
No reason given
Edited by LemonDrop