For instance,
int i = 0;
for( ; i < 5; ++i )
{
doStuff();
}
Versus
for( int i = 0; i < 5; ++i )
{
doStuff();
}
The only time I have seen the first method is when the variable to be initialized is a really long named iterator. Is there anything performance wise that would make one more beneficial? Or is it merely choice and readability?
One reason you might do this is because you need to know the value of the iterator/index after the loop has ended. That doesn't really make sense with your example, because you know the value will be 5, but sometimes you do not know this in advance. Consider:
int i = 0;
for(; isStillOkay(i); ++i )
{
doStuff();
}
// now we can use the final value of i for something
In general, the only reason you could have to do this is to make sure the iterator/index is available in the enclosing scope. If you don't need that, all you are doing is polluting that scope. As always, the advice is to give all objects the smallest scope necessary.
If you have long types, I recommend you use auto to deduce the types for you. If you don't have C++11 support, I then recommend the following formatting:
for (std::some::very_long<type>::name iterator_name = some_big_initializer;
iterator_name < complicated && condition != iterator_name;
++iterator_name)
{
// ...
}
No need for initialization when you have a good reason for an infinite loop:
bool run(){
for(;;){
if(ERROR)
break;
}
}
Related
I have a function memoize that reads and writes a static std::map, eg:
int memoize(int i)
{
static std::map<int,int> map;
const auto iterator = memoizer.find(i);
if (iterator == memoizer.end())
memoizer[i]=i+1;
else
return iterator->second;
}
memoize is called by other functions which are called by other functions which are called.... by functions in main. Now if in main I have something like
#pragma omp parallel for
for (int i=0; i<1000; i+++)
f(i); \\function calling memoize
for (int i=0; i<1000; i+++)
g(i); \\function calling memoize
then I have a problem in the first loop since std::map is not thread safe. I am trying to figure out a way to lock the static map only if openmp is used (thus only for the first loop). I would rather avoid having to rewrite all functions to take an extra omp_lock_t argument.
What's the best way to achieve that? Hopefully with the least amount of macros possible.
A very simple solution to your problem would be to protect both the read and the update parts of your code with a critical OpenMP directive. Of course, to reduce the risk of unwanted interaction/collision with some other critical you might already have somewhere else in your code, you should give it a name to identify it clearly. And should your OpenMP implementation permit it (ie the version of the standard being high enough), and also if you have the corresponding knowledge, you can add a hint on how much of contention you expect from this update among the threads for example.
Then, I would suggest you to check whether this simple implementation gives you sufficient performance, meaning whether the impact of the critical directive isn't too much performance-wise. If you're happy with the performance, then just leave it as is. If not, then come back with a more precise question and we'll see what can be done.
For the simple solution, the code could look like this (with here a hint suggesting that high contention is expected, which is only a example for your sake, not a true expectation of mine):
int memoize( int i ) {
static std::map<int,int> memoizer;
bool found = false;
int value;
#pragma omp critical( memoize ) hint( omp_sync_hint_contended )
{
const auto it = memoizer.find( i );
if ( it != memoizer.end() ) {
value = it->second;
found = true;
}
}
if ( !found ) {
// here, we didn't find i in memoizer, so we compute it
value = compute_actual_value_for_memoizer( i );
#pragma omp critical( memoize ) hint( omp_sync_hint_contended )
memoizer[i] = value;
}
return value;
}
It acts like this.
fun();//return 1;
for (int i=0;i++;i<100)
fun();//return 2;
fun();//return 3;
I don't want to do it manually, like:
static int i=0;
fun(){return i};
main()
{
i++;
fun();//return 1;
i++;
for (int i=0;i++;i<100)
fun();//return 2;
i++;
fun();//return 3;
}
New classes and static variables are allowed.
I am trying to design a cache replacement algorithm. Most of the time I use the LRU algorithm, but, if I use LRU algorithm inside a loop I would very likely get a cache thrashing.
https://en.wikipedia.org/wiki/Thrashing_(computer_science)
I need to know if I am inside a loop. Then I can use the LFU algorithm to avoid thrashing.
An obvious way of doing this would be using the __LINE__ macro. It will return the source code line number, which will be different throughout your function.
It is not possible within c++ for a function to know whether or not it is inside a loop 100% of the time. However, if you are happy to do some manual coding to tell the function that it is inside a loop then making use of C++'s default parameters you could simply implement a solution. For more information on default parameters see http://www.learncpp.com/cpp-tutorial/77-default-parameters/. Also, because Global variables are generally frowned upon I have placed them in a separate namespace in order to prevent clashes.
namespace global_variables {
int i = 0;
}
int func(bool is_in_loop = false) {
if (is_in_loop)
{
//do_something;
return global_variables::i;
}
else
{
//do_something_else;
return global_variables::i++;
}
}
int main()
{
// Calling function outside of loop
std::cout << func();
// Calling function inside of loop
for (int j=0;j<100;j++)
{
// is_in_loop will be overided to be true.
std::cout << function(true);
}
return 0;
}
I have a class Character that inherits from a base class CollidableObject. CollidableObject has, as you may have guessed, methods to detect collisions between other CollidableObjects, such as CircleCollidableObject and SquareCollidableObject.
bool CollidableObject::collidesWith(std::shared_ptr<CollidableObject> &pCollidable)
{
...
}
I use this to run other checks, and eventually handle the collision. Basically I want to be able to loop through the characters in my game, pass in two Characters (that, again, inherit from CollidableObject), and detect any collisions.
void CharacterManager::collisions()
{
for(std::vector<std::shared_ptr<Character>>::iterator i = mCharacters_.begin(); i != mCharacters_.end(); i++) {
for(std::vector<std::shared_ptr<Character>>::iterator j = mCharacters_.begin(); j != mCharacters_.end(); j++) {
if(i == j) continue;
(*i)->collidesWith(*j);
...
}
I'd rather not make the mCharacters_ vector into a vector of CollidableObjects if I dont have to. But I'm not sure if that's the only way.
Can you rewrite the interface? There's nothing wrong with having:
bool CollidableObject::collidesWith(const CollidableObject* pCollidable)
Presumably collidesWith isn't going to take ownership of the pointer you pass in, so passing in a raw pointer is fine.
That said, shared_ptr<CollidableObject> is actually constructible from shared_ptr<Character>. So if you want to take a shared_ptr, you'll have to take it by const reference instead of by reference. That is:
bool CollidableObject::collidesWith(const std::shared_ptr<CollidableObject>& p)
or just by-value:
bool CollidableObject::collidesWith(std::shared_ptr<CollidableObject> p)
See constructor #9 from this reference.
And if you're using std::shared_ptr, you should at least use auto in your loops to reduce the verbosity. And the j loop can start one-past i to avoid double-checking every pair:
for (auto i = mCharacters_.begin(); i != mCharacters_.end(); ++i) {
for (auto j = std::next(i); j != mCharacters_.end(); ++j) {
(*i)->collidesWith(j->get());
...
}
}
Although the example below compiles fine except for the last line with the error, I'd like to know the ins and outs of this 'scoping' within a scope? Also the terminology of this, if any.
Consider these brackets:
void func()
{
int i = 0;
{ // nice comment to describe this scope
while( i < 10 )
++i;
}
{ // nice comment to describe this scope
int j= 0;
while( j< 10 )
++j;
}
i = 0; // OK
// j = 0; // error C2065
}
consider this:
error C2065: 'j' : undeclared identifier
edit:
Accepted answer is from bitmask, although I think everyone should place it in the context of anio's answer. Especially, quote: "perhaps you should break your function into 2 functions"
Do. By all means!
Keeping data as local as possible and as const as possible has two main advantages:
side effects are reduced and the code becomes more functional
with complex objects, destructors can be be invoked early within a function, as soon as the data is not needed any more
Additionally, this can be useful for documentation to summarise the job a particular part of a function does.
I've heard this being referred to as explicit or dummy scoping.
I personally don't find much value in adding additional scoping within a function. If you are relying on it to separate parts of your function, perhaps you should break your function into 2 functions. Smaller functions are better than larger ones. You should strive to have small easily understood functions.
The one legitimate use of scopes within a function is for limiting the duration of a lock:
int doX()
{
// Do some work
{
//Acquire lock
} // Lock automatically released because of RAII
}
The inner scope effectively limits the code over which the lock is held. I believe this is common practice.
Yes, definitely - it's a great habit to always keep your variables as local as possible! Some examples:
for (std::string line; std::getline(std::cin, line); ) // does not
{ // leak "line"
// process "line" // into ambient
} // scope
int result;
{ // putting this in a separate scope
int a = foo(); // allows us to copy/paste the entire
a += 3; // block without worrying about
int b = bar(a); // repeated declarators
result *= (a + 2*b);
}
{ // ...and we never really needed
int a = foo(); // a and b outside of this anyway!
a += 3;
int b = bar(a);
result *= (a + 2*b);
}
Sometimes a scope is necessary for synchronisation, and you want to keep the critical section as short as possible:
int global_counter = 0;
std::mutex gctr_mx;
void I_run_many_times_concurrently()
{
int a = expensive_computation();
{
std::lock_guard<std::mutex> _(gctr_mx);
global_counter += a;
}
expensive_cleanup();
}
The explicit scoping is usually not done for commenting purposes, but I don't see any harm in doing it if you feel it makes your code more readable.
Typical usage is for avoiding name clashes and controlling when the destructors are called.
A pair of curly braces defines a scope. Names declared or defined within a scope are not visible outside that scope, which is why j is not defined at the end. If a name in a scope is the same as a name defined earlier and outside that scope, it hides the outer name.
I was making a "concatenating iterator", i.e. an iterator that would iterate over the ints in an int**.
Its constructor needs:
An array of T**, representing the beginning of each sub-array.
An array of T**, representing the end of each sub-array.
Lo and behold, I ran across a situation where goto seemed to be appropriate.
But something within me screamed "NO!!" so I thought I'd come here and ask:
Should I try avoid goto situations like this? (Does it improve the readability if I do?)
#include <algorithm>
template<class T>
class lazy_concat_iterator
{
// This code was meant to work for any valid input iterator
// but for easier reading, I'll assume the type is: T**
mutable T** m_endIt; // points to an array of end-pointers
mutable T** m_it; // points to an array of begin-pointers
mutable bool m_started; // have we started iterating?
mutable T* m_sub; // points somewhere in the current sub-array
mutable T* m_subEnd; // points to the end of the current sub-array
public:
lazy_concat_iterator(T** begins, T** ends)
: m_it(begins), m_endIt(ends), m_started(false) { }
void ensure_started() const
{
if (!m_started)
{
m_started = true;
INIT:
m_sub = *m_it;
m_subEnd = *m_endIt;
if (m_sub == m_subEnd) // End of this subarray?
{
++m_it;
++m_endIt;
goto INIT; // try next one <<< should I use goto here?
}
}
}
};
How you could use it:
#include <vector>
#include <cstring>
using namespace std;
int main(int argc, char* argv[])
{
vector<char*> beginnings(argv, argv + argc);
vector<char*> endings;
for (int i = 0; i < argc; i++)
endings.push_back(argv[i] + strlen(argv[i]));
lazy_concat_iterator<char> it(&beginnings[0], &endings[0]);
it.ensure_started(); // 'it' would call this internally, when dereferenced
}
Yes, you can and should avoid goto, for example this code should do the equivalent for what yours does from the INIT label (this also works for input iterators which was a "hidden requirement" as it doesn't dereference m_it and m_endIt an extra time once the condition is met unlike my previous transformation):
while ((m_subIt = *m_it) == (m_subEnd = *m_endIt))
{
++m_it;
++m_endIt;
}
Previous answer attempt:
Even a forever loop would be clearer and neater than a goto. It highlights the obvious "never terminate" possibility even better.
for (;;)
{
m_sub = *m_it;
m_subEnd = *m_endIt;
if (m_sub != m_subEnd)
break;
++m_it;
++m_endIt;
}
Although I don't see why you need to assign to m_subEnd and m_subIt inside the loop. If you don't you can rewrite this as a while loop:
while (*m_it == *m_endIt)
{
++m_it;
++m_endIt;
}
m_subIt = *m_it;
m_subEnd = *m_endIt;
while (*m_it == *m_endIt)
{
++m_it;
++m_endIt;
}
m_sub = *m_it;
m_subEnd = *m_endIt;
Maybe no for loop, but maybe a do-while?
do {
m_sub = *m_it;
m_subEnd = *m_endIt;
if (m_sub == m_subEnd) // End of this subarray?
{
++m_it;
++m_endIt;
}
} while (m_sub == m_subEnd);
If you don't want to do the comparison twice and still avoid using one of goto's stealth cousins break or continue:
bool anotherround = FALSE;
do {
m_sub = *m_it;
m_subEnd = *m_endIt;
anotherround = m_sub == m_subEnd
if (anotherround) // End of this subarray?
{
++m_it;
++m_endIt;
}
} while (anotherround);
With your knowledge of the context I'm sure you can invent better varnames, but that's the idea.
Regarding a goto's influence on readability: for me the main issue with a goto herey is that it forces the programmer to memorize a potential nonlogical movement in the code - all of a sudden the code can jump almost anywhere. If you use control structures, even if you have to introduce some extra lines or whatnot, the program continues to behave as expected and follow the flow. And in the long run, that's what readability is all about.
Don't use a goto. The only case when a goto can be forgiven is if you have a complicated function (which you shouldn't have anyways) and you want to have a centralized exit/cleanup part at the end of the function, where you could goto upon different errors at different parts of the function, or fall through upon success.
All in all, you should use a do-while loop here.
People created middle and high level compilers with using assembler(and high-level assembler). Assembler has many jmp jnz jg jl commands act like goto. They made it this far. Cant you do the same? If you can't then you answered your own question.
I cant say the same thing for interpreters.