implementing retry in while loop - c++

I am trying to implement a retry in the while loop. I want to retry 5 times and if the flag becomes true.
bool flag = false;
unsigned int count = 5;
while(!flag && count > 0) {
DataOperation opt = DataUser::Insert(data_point);
if(opt == DataOperation::DataEnum) {
UserPointData exist = DataUser::FindUser(data_point->user_id());
if(exist) {
exist->attributeData.put(key, value, len_value, client_id, last_modified_date);
flag = true;
}
} else {
// insert in data_point
data_point->attributeData.put(key, value, len_value, client_id, last_modified_date);
flag = true;
}
count--;
}
So if flag becomes true, then I will exit out of the loop
Second case, if flag is false for 5 times, then I will exit out of the loop as well.
Does this look right what I am doing?

Just like #Borgleader pointed out, the flag variable is unnecessary. You can stick with a break instruction and check after the loop if the count is still bigger than zero. If so, means your task succeeded.
unsigned int count = 5;
while(count > 0) {
DataOperation opt = DataUser::Insert(data_point);
if(opt == DataOperation::DataEnum) {
UserPointData exist = DataUser::FindUser(data_point->user_id());
if(exist) {
exist->attributeData.put(key, value, len_value, client_id, last_modified_date);
break; // success.
}
} else {
// insert in data_point
data_point->attributeData.put(key, value, len_value, client_id, last_modified_date);
break; // success.
}
count--;
}
if (count > 0) { /* succeeded within 5 tries. */ }

What you are doing seems fine but possibly more complicated than it needs to be.
For example you don't need to set a flag to exit you can simply call break;.
Here is a pattern I sometimes use that maybe simpler:
bool succeed_at_doing_stuff()
{
std::cout << "trying" << '\n';
return false;
}
int main()
{
int retries = 3;
while(retries--) // will exit when retries == 0, retries then becomes -1
{
if(succeed_at_doing_stuff())
break; // no need to set a flag
// take alternative action
}
if(retries < 0) // retries was decremented after last check
{
std::cerr << "error: gave up - too many retries" << std::endl;
return 1;
}
}

If you will use count variable only for that purpose, I suggest you to use a for loop so count will not be visible and memory of it will be reclaimed after exiting the scope of the loop. And use break statement to immediately exit the loop.
for(auto count = 0; count<5; ++count) {
DataOperation opt = DataUser::Insert(data_point);
if(opt == DataOperation::DataEnum) {
UserPointData exist = DataUser::FindUser(data_point->user_id());
if(exist) {
exist->attributeData.put(key, value, len_value, client_id, last_modified_date);
break;
}
} else {
// insert in data_point
data_point->attributeData.put(key, value, len_value, client_id, last_modified_date);
break;
}
}

The only change I would make is
if(opt == DataOperation::DataEnum) {
UserPointData exist = DataUser::FindUser(data_point->user_id());
if(exist) {
exist->attributeData.put(key, value, len_value, client_id, last_modified_date);
flag = true;
} else {
count--;
}
I am not crazy about you setting count to 5 then counting down, as it is more obvious if you increment until you reach 5, but this will work.
You may want to break instead of setting flag, unless you are planning on using flag to differentiate between finding a match or exiting due to the conditional.

Related

What is the problem with this boolean function?

I was wondering what I may have done wrong in writing this simple function which is supposed to return true if the given number is a prime, or false if not a prime.
bool isPrime(int num)
{
if (num <= 1)
{
status = false;
}
else
{
for (int i = 1; i <= num; i++)
{
if (num % i == 0)
{
dividers++;
}
}
if (dividers == 2)
{
status = true;
}
else
{
status = false;
}
}
return status;
}
Obviously, my main looks like this:
bool isPrime(int num);
bool status;
int dividers = 0;
int main() {
isPrime(2);
if (!isPrime)
{
std::cout << "Not prime" << std::endl;
}
else
{
std::cout << "Prime" << std::endl;
}
return 0;
}
I'm a C++ beginner and I'd really appreciate it if someone could help me there and correct my logic.
Have a good day:)
The immediate problem is in this two lines:
isPrime(2);
if (!isPrime)
The first line calls the function and discards the returned value. The second line converts a pointer to the function to bool. The output of your code does not depend on what you actually do in isPrime.
That is not how you call a function and use its result!
Instead you want
if (isPrime(2)) {
or
bool isP = isPrime(2);
if (isP) { ...
As mentioned in comments, there are also problems in the implementation of isPrime, but I hope this is enough to set you back on the right track.
PS: You should get rid of the global variable status. You do not need both, the return value and a global that stores the result, and if you can choose, you should definitely go for the return value.

How to fix this statement may fall through [-Werror=implicit-fallthrough=]?

What does
this statement may fall through [-Werror=implicit-fallthrough=]
mean ?
I getting this error while compiling at statement like this:
switch(eT)
{
case SEL_CRIT:
{
TYPE1* psSel;
iRetVal = dbseq(enB->m_ps,
NULL, NULL, &esM, NULL, ESEC);
while (iRetVal == 0)
{
if(psEnterprise)
{
bool iFound = false;
for (i = 0; i< psME->m_pslave[0].m_uc; i++)
{
ENT node1;
sEOS = psME>m_pslave[0].m_pslavecnt[i];
}
if (iFound && (psME->m_NOTOVERLOADED == false))
{
return psME;
}
}
}
psSel = (M_EN*)pCrit;
LOG_INFO(FAIL_TO_LOAD, psME->m_ONG, psME->EN);
int_Enterprise = NULL;
}
at
int_Enterprise = NULL;
where
int_Enterprise is some structure pointer.
How can I fix this?
You have no break; at the end of your case: so execution will fall through into the next case. Add a break statement to prevent fall-through if that's what you want or add a [[fallthrough]] attribute if fallthrough is intended.

Clang Format chained else ifs on single lines

I'm trying to write a .clang-format file that will allow the following:
if (value.Is<bool>()) { index = 1; }
else if (value.Is<int>()) { index = 2; }
else if (value.Is<unsigned int>()) { index = 3; }
else if (value.Is<long long>()) { index = 4; }
else if (value.Is<unsigned long long>()) { index = 5; }
else if (value.Is<float>()) { index = 6; }
else if (value.Is<double>()) { index = 7; }
else if (value.Is<long double>()) { index = 8; }
else if (value.Is<std::string>()) { index = 9; }
else if (value.IsArray()) { index = 10; }
else { index = 0; }
I've tried every option I can find related to breaks and allowShort*, and no matter what I do it seems to split them into multi-lines after the first like so:
if (value.Is<bool>()) { index = 1; }
else if (value.Is<int>()) {
index = 2;
}
...
Is there some option I'm missing that could support this?
Unfortunately, this is currently not supported for if-else statements, only for simple if's (as of revision 329373, dating 6/4/18). The AllowShortBlocksOnASingleLine and AllowShortIfStatementsOnASingleLine options are not applicable for if-else statements.
Hopefully this will change in the future.
The doc is not explicit about this, saying that AllowShortIfStatementsOnASingleLine will allow simple if statements on a single line:
AllowShortIfStatementsOnASingleLine (bool)
If true, if (a) return; can be put on a single line.
However, clang-format code suggests that if-else blocks are not allowed on single lines:
1) UnwrappedLineFormatter.cpp, tryMergeSimpleControlStatement:
// Only inline simple if's (no nested if or else).
if (I + 2 != E && Line.startsWith(tok::kw_if) &&
I[2]->First->is(tok::kw_else))
return 0;
2) FormatTest.cpp, FormatShortBracedStatements test.
Notice the test parameters, and that in the expected formatting in the unittests, else always resides in its own line, while plain if statements with no else are on a single line with their blocks, for example:
verifyFormat("if (true) {\n"
" f();\n"
"} else {\n"
" f();\n"
"}",
AllowSimpleBracedStatements);
https://clang.llvm.org/docs/ClangFormatStyleOptions.html says:
SIS_AllIfsAndElse (in configuration: AllIfsAndElse) Always put short ifs, else >ifs and else statements on the same line.
if (a) return;
if (b) return;
else return;
if (c) return;
else {
return;
}

Function checking values of type chars

I am new to programming and have an exercise in which I create a function to check whether an array of type char hold particular values.
Here is my function:
bool arrCheck(char n[],char pos1,char pos2,char pos3,int size)
{
int n1,n2,n3;
for (int i=0;i<size;i++)
{
if (n[i]==pos1)
{
n1=1;
}
if (n[i]==pos2)
{
n2=1;
}
if (n[i]==pos3)
{
n3=1;
}
}
if ((n1==1)&&(n2==1)&&(n3==1))
{
return true;
}
}
here is my test program:
int main()
{
char a[5]={'6','1','a','a','a'};
if (arrCheck(a,'1','6','9',5))
{
cout<<"true\n";
}
}
I thought the result is supposed to be false but all I got is true. What did I do wrong?
n1, n2 and n3 are default-initialized and they have indeterminate values at first. Initialize them before checking their values. Also do not forget to return something even when the condition is false.
Try this:
bool arrCheck(char n[],char pos1,char pos2,char pos3,int size)
{
int n1=0,n2=0,n3=0;
for (int i=0;i<size;i++)
{
if (n[i]==pos1)
{
n1=1;
}
if (n[i]==pos2)
{
n2=1;
}
if (n[i]==pos3)
{
n3=1;
}
}
return (n1==1)&&(n2==1)&&(n3==1);
}
Using boolto store boolean values and using const to mark that the contents of array won't be changed may be better .
bool arrCheck(const char n[],char pos1,char pos2,char pos3,int size)
{
bool n1=false,n2=false,n3=false;
for (int i=0;i<size;i++)
{
n1=n1||(n[i]==pos1);
n2=n2||(n[i]==pos2);
n3=n3||(n[i]==pos3);
}
return n1&&n2&&n3;
}
1) Use a bool variable instead of three int variable
2) Initialize it (You have not initialized the int variable and they have random garbage value)
3) Also add else condition to return false value (Your code is not returning false).
4)Also print false in main function using else condition.
Hope this helps you..!
THE CODE IS ALRIGHT. You just forgot to add some statements and this is causing the error (it might or might not have been silly on your part).
Your definition of the function arrCheck() is incomplete. It returns true if a certain condition is fulfilled but what if it isn't? In that case, you must return false. But in your code, false is never returned. So firstly, you've gotta add an else statement after the last if statement in the arrCheck() method to this:
if((n1==1)&&(n2==1)&&(n3==1)){
return true;
}
else{
return false; //this has to be added
}
It can now return false if such a case is encountered.
Also, you must display "false" in the main method if arrCheck() returns false. You are recommended to add an else statement after the if statement in the main() method. See the modification below:
if (arrCheck(a,'1','6','9',5))
{
cout<<"true\n";
}
else{
cout<<"false\n"; //it must show false;
}
Once you correct these, your code will produce the correct output.
P.S. This answer serves as an elaboration of the answer earlier submitted by #KUSHAGRA GUPTA.
int n1,n2,n3;
This line leads to undefined behaviour because you do not initialise the variables yet attempt to read from them later on even if not all of them have been assigned a value:
if ((n1==1)&&(n2==1)&&(n3==1))
Fix the undefined behaviour by initialising the variables to 0:
int n1 = 0;
int n2 = 0;
int n3 = 0;
There is another case of undefined behaviour when your function does not state what to return if the condition is not true. Fix this, too:
if ((n1==1)&&(n2==1)&&(n3==1))
{
return true;
}
else
{
return false;
}
Or simply:
return (n1==1)&&(n2==1)&&(n3==1);
change that line to like this.int n1= 0,n2= 0,n3 = 0;
because when uninitialized these variable have garbage values.
bool arrCheck(char n[],char pos1,char pos2,char pos3,int size)
{
int first = 0,second = 0, third = 0;
for (int i=0;i<size;i++) {
if (n[i]==pos1) {
first = 1;
} else if (n[i]==pos2) {
second = 1;
} else if (n[i]==pos3) {
third = 1;
}
}
if( first+ second + third == 3)
return true;
else
return false;
}

Searching first specified element in array

I'm trying to make function that has a loop that checks every member of an array made from boolean variables and exits when it finds the first "true" value.
That's what I have now:
bool solids[50];
int a,i;
//"equality" is a function that checks the equality between "a" and a defined value
solids[0] = equality(a,&value_1);
solids[1] = equality(a,&value_1);
solids[2] = equality(a,&value_1);
solids[3] = equality(a,&value_1);
for (i = 0; solids[i] != true; i++)
{
[...]
}
But I have no idea, what should I put into the loop?
My attempt was
for (i = 0; i <= 50; i++)
{
if (solids[i] == true)
{
return true;
break;
} else {
return false;
}
}
,that should return true after the first found true and return false if the array has no member with true value, but it doesn't seem to work in the code.
Is it wrong? If yes, what is the problem?
PS.: I may count the number of trues with a counter but that's not an optimal solve to the problem, since I just look for the FIRST true value and consequently, the program doesn't have to check all the 50 members. Needley to count, how many unnecesary steps should this solve would mean.
here's a short example usage of std::find() as advised by #chris:
bool find_element_in_array() {
bool solids[50];
int length;
/* ... do many operations, and keep length as the size of values inserted in solids */
bool* location = std::find(solids, length, true);
// if element is found return true
if (location != solids + length)
return true;
// else return false
return false;
}
Once you have solids correctly set (it looks like you're currently setting every value to the same thing), you can make a loop that exits on the first true like this:
for (i = 0; i < 50; i++)
{
if (solids[i] == true)
{
return true;
}
}
return false;
I'd also just move the declaration of i into the for loop body, since it's not used outside, but the above answers your question.
return immediately exits the function, so there is no need to break the loop after.
If it's sufficient to exit the function right after the search, you should write something like:
for (int i = 0; i < 50; i++) {
if (solids[i]) return true;
}
return false;
If you need to use the result of the search in the same function, use additional variable:
bool found = false;
for (int = 0; i < 50; i++) {
if (solids[i]) {
bool = true;
break;
}
}
if (found) { ...