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

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.

Related

How to get multiple selected values from listbox in mfc

I am making a music player program using MFC.
I would like to add a function to select multiple values ​​in the listbox and delete them, but I would like to ask for advice.
The option of the listbox is Extended, and multiple selection using the control keys is fine.
Among the methods of listbox, it seems to be possible to use SetSel, GetCursel, GetSelItems, etc, but I can't solve it.
I would appreciate it if you could give me a simple advice.
Thank you very much.
void CMFC_MP3Dlg::DeleteList(CStatus* head)
{
CFileFind finder;
CString strTemp;
CString strRemoveFile;
POSITION pos;
CStatus* pTemp = new CStatus();
CStatus* pPrev = new CStatus();
//int nSelCount = m_ListBox.GetCurSel();
//m_ListBox.GetText(nSelCount, strTemp);
LPINT lpSelItems = new int[m_nListBoxCount];
m_ListBox.GetSelItems(m_nListBoxCount, lpSelItems);
for (int nCount = 0; nCount <= m_nListBoxCount; nCount ++)
{
if(m_ListBox.SetSel(nCount,1))
{
m_ListBox.GetText(nCount, strTemp);
m_vec.push_back(strTemp);
}
}
std::vector<CString>::iterator iter;
for(iter = m_vec.begin(); iter != m_vec.end();)
{
strRemoveFile.Format(_T("C:\\MFC_MP3\\%s"), *iter);
BOOL bRet = finder.FindFile(strRemoveFile);
if(bRet)
{
if(DeleteFile(strRemoveFile))
{
pPrev = NULL;
pTemp = head;
if(pTemp == NULL)
{
return;
}
while(pTemp->m_strFileName != strTemp)
{
pPrev = pTemp;
pTemp = pTemp->m_right;
}
if(pTemp->m_strFileName == strTemp)
{
pPrev->m_right = pTemp->m_right;
pTemp->m_right->m_left = pPrev;
delete pTemp;
}
MessageBox(_T("삭제 성공!"));
ShowList();
}
else
{
MessageBox(_T("삭제 실패!"));
}
}
else
{
MessageBox(_T("File Not Found!"));
}
iter++;
}
}
Does this help?
void CChristianLifeMinistryPersonalCopiesDlg::BuildSelectedArray()
{
int i, iSize, *pIndex;
CString strText;
m_aryStrPublishers.RemoveAll();
// get selected count
iSize = m_lbPublishers.GetSelCount();
if (iSize > 0)
{
pIndex = new int[iSize];
m_lbPublishers.GetSelItems(iSize, pIndex);
for (i = 0; i < iSize; i++)
{
m_lbPublishers.GetText(pIndex[i], strText);
m_aryStrPublishers.Add(strText);
}
delete[] pIndex;
}
}
This works fine for me.
Note that your code is incomplete though. We don't see you specify what the count is of the selected items. And we don't see you reset your vector array before you begin.
Have you actually debugged your code to see where it fails?

Why if statement is not entering when Null

I have the next code, and when raiz is NULL is not entering the if statement
I already tried to do the other way like if(raiz != NULL) and in the else statement trying to run the code :
masAlto = 1;
raiz = Nuevo;
Here is my code:
void InsertaAVL(arbolAVL *raiz, arbolAVL *Nuevo, int masAlto)
{
arbolAVL *a = raiz;
int subarbolmasAlto = FALSO;
if (raiz == NULL)
{
masAlto = 1;
raiz = Nuevo;
}
else
{
if (raiz->llave > Nuevo->llave)
{
//Insertar a la Izquierda
InsertaAVL(raiz->Izq, Nuevo, subarbolmasAlto);
if (subarbolmasAlto == VERDADerO)
{
switch(raiz->FBalance)
{
case LH : BalanceIzquierdo(raiz,masAlto);
break;
case RH : raiz->FBalance = EH;
masAlto = FALSO;
break;
case EH : raiz->FBalance = LH;
masAlto = VERDADerO;
break;
}
}
else
masAlto = FALSO;
}
else
{
InsertaAVL(raiz->Der, Nuevo, subarbolmasAlto);
if (subarbolmasAlto == VERDADerO)
{
switch(raiz->FBalance)
{
case LH : raiz->FBalance = EH;
break;
case RH : BalanceDerecho(raiz,masAlto);
break;
case EH : raiz->FBalance = RH;
masAlto = VERDADerO;
break;
}
}
else
masAlto = FALSO;
}
}
}
I expect that when raiz is NULL to enter the code inside the if statement
It does enter the if statement true branch, although I'd prefer if (!raiz) as the conditional as this behaves well with the NULL of C and the nullptr of C++. Effectively though the true branch is a no-op since the assignments
masAlto = 1;
raiz = Nuevo;
have no effect on the quantities passed by the caller of the function. Did you want int* masAlto &c. as the parameters?

implementing retry in while loop

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.

Dangling memory/ unallocated memory issue

I've this piece of code, which is called by a timer Update mechanism.
However, I notice, that the memory size of the application, while running, continuously increases by 4, indicating that there might be a rogue pointer, or some other issue.
void RtdbConnection::getItemList()
{
std::vector<CString> tagList = mItemList->getItems();
//CString str(_T("STD-DOL1"));
PwItemList* pil = mPwSrv->GetItemList();
CPwItem pw ;
for(auto it = tagList.begin(); it != tagList.end(); ++it)
{
pw = mPwSrv->GetItem(*it);
pil->AddItem(&(PwItem)pw);
}
pil->AddInfo(DB_DESC); //Description
pil->AddInfo(DB_QALRM); // Alarm Status
pil->AddInfo(DB_QUNAK); //UNACK status
pil->AddInfo(DB_AL_PRI); // Priority of the alarm tag
pil->ExecuteQuery();
int i = 0;
for (auto it = tagList.begin(); i < pil->GetInfoRetrievedCount() && it != tagList.end(); i+=4, it++)
{
//item = {0};
CString str(*it);
PwInfo info = pil->GetInfo(i);
CString p(info.szValue().c_str());
bool isAlarm = pil->GetInfo(i+1).bValue();
bool isAck = pil->GetInfo(i+2).bValue();
int priority = pil->GetInfo(i+3).iValue();
item = ItemInfo(str, p, isAlarm, isAck, priority);
//int r = sizeof(item);
mItemList->setInfo(str, item); // Set the details for the item of the List
}
delete pil;
pil = NULL;
}
I cannot seem to find a memory block requiring de-allocation here. Nor is there any allocation of memory when I step inside the following function :
mItemList->setInfo(str, item);
which is defined as :
void ItemList::setInfo(CString tagname, ItemInfo info)
{
int flag = 0;
COLORREF tempColour;
std::map<CString, ItemInfo>::iterator tempIterator;
if ( (tempIterator = mAlarmListMap.find(tagname)) !=mAlarmListMap.end() )
{
//remove the current iteminfo and insert new one
if(mAlarmListMap[tagname].getPriority() != info.getPriority() && (mAlarmListMap[tagname].getPriority()!=0))
{
mAlarmListMap[tagname].updatePriority(info.getPriority());
mAlarmListMap[tagname].mPrioChanged = TRUE;
}
else
{
mAlarmListMap[tagname].mPrioChanged = FALSE;
((mAlarmListMap[tagname].getPrevPriority() != 0)?(mAlarmListMap[tagname].ResetPrevPriority()):TRUE);
mAlarmListMap[tagname].setPriority(info.getPriority());
}
mAlarmListMap[tagname].setDescription(info.getDescription());
mAlarmListMap[tagname].setAlarm(info.getAlarmStat());
mAlarmListMap[tagname].setAlarmAck(info.getAckStat());
tempColour = mColourLogic->setUpdatedColour(mAlarmListMap[tagname].getAlarmStat(), mAlarmListMap[tagname].getAckStat(), flag);
mAlarmListMap[tagname].setColour(tempColour);
if(!(info.getAlarmStat() || info.getAckStat()))
{
flag = 1;
mAlarmListMap[tagname].mIsRTN = true;
mAlarmListMap[tagname].setDisplayCondition(false);
}
else
{
mAlarmListMap[tagname].setDisplayCondition(true);
}
//((mAlarmListMap[tagname].mIsRTN == true)?
}
else
{
tempIterator = mAlarmListMap.begin();
tempColour = mColourLogic->fillColourFirst(info.getAlarmStat(), info.getAckStat());
info.setColour(tempColour);
mAlarmListMap.insert(tempIterator, std::pair<CString,ItemInfo>(tagname,info));
}
}
I tried juggling with the allocations, but the increase is always a constant 4.
Could anyone kindly look and highlight where the issue could be?
Thanks a lot.

Easiest way to flip a boolean value?

I just want to flip a boolean based on what it already is. If it's true - make it false. If it's false - make it true.
Here is my code excerpt:
switch(wParam) {
case VK_F11:
if (flipVal == true) {
flipVal = false;
} else {
flipVal = true;
}
break;
case VK_F12:
if (otherVal == true) {
otherValVal = false;
} else {
otherVal = true;
}
break;
default:
break;
}
You can flip a value like so:
myVal = !myVal;
so your code would shorten down to:
switch(wParam) {
case VK_F11:
flipVal = !flipVal;
break;
case VK_F12:
otherVal = !otherVal;
break;
default:
break;
}
Clearly you need a factory pattern!
KeyFactory keyFactory = new KeyFactory();
KeyObj keyObj = keyFactory.getKeyObj(wParam);
keyObj.doStuff();
class VK_F11 extends KeyObj {
boolean val;
public void doStuff() {
val = !val;
}
}
class VK_F12 extends KeyObj {
boolean val;
public void doStuff() {
val = !val;
}
}
class KeyFactory {
public KeyObj getKeyObj(int param) {
switch(param) {
case VK_F11:
return new VK_F11();
case VK_F12:
return new VK_F12();
}
throw new KeyNotFoundException("Key " + param + " was not found!");
}
}
:D
</sarcasm>
Easiest solution that I found:
x ^= true;
If you know the values are 0 or 1, you could do flipval ^= 1.
Just for information - if instead of an integer your required field is a single bit within a larger type, use the 'xor' operator instead:
int flags;
int flag_a = 0x01;
int flag_b = 0x02;
int flag_c = 0x04;
/* I want to flip 'flag_b' without touching 'flag_a' or 'flag_c' */
flags ^= flag_b;
/* I want to set 'flag_b' */
flags |= flag_b;
/* I want to clear (or 'reset') 'flag_b' */
flags &= ~flag_b;
/* I want to test 'flag_b' */
bool b_is_set = (flags & flag_b) != 0;
Just because my favorite odd ball way to toggle a bool is not listed...
bool x = true;
x = x == false;
works too. :)
(yes the x = !x; is clearer and easier to read)
This seems to be a free-for-all ... Heh. Here's another varation, which I guess is more in the category "clever" than something I'd recommend for production code:
flipVal ^= (wParam == VK_F11);
otherVal ^= (wParam == VK_F12);
I guess it's advantages are:
Very terse
Does not require branching
And a just as obvious disadvantage is
Very terse
This is close to #korona's solution using ?: but taken one (small) step further.
The codegolf'ish solution would be more like:
flipVal = (wParam == VK_F11) ? !flipVal : flipVal;
otherVal = (wParam == VK_F12) ? !otherVal : otherVal;
flipVal ^= 1;
same goes for
otherVal
I prefer John T's solution, but if you want to go all code-golfy, your statement logically reduces to this:
//if key is down, toggle the boolean, else leave it alone.
flipVal = ((wParam==VK_F11) && !flipVal) || (!(wParam==VK_F11) && flipVal);
if(wParam==VK_F11) Break;
//if key is down, toggle the boolean, else leave it alone.
otherVal = ((wParam==VK_F12) && !otherVal) || (!(wParam==VK_F12) && otherVal);
if(wParam==VK_F12) Break;
Clearly you need a flexible solution that can support types masquerading as boolean. The following allows for that:
template<typename T> bool Flip(const T& t);
You can then specialize this for different types that might pretend to be boolean. For example:
template<> bool Flip<bool>(const bool& b) { return !b; }
template<> bool Flip<int>(const int& i) { return !(i == 0); }
An example of using this construct:
if(Flip(false)) { printf("flipped false\n"); }
if(!Flip(true)) { printf("flipped true\n"); }
if(Flip(0)) { printf("flipped 0\n"); }
if(!Flip(1)) { printf("flipped 1\n"); }
No, I'm not serious.
For integers with values of 0 and 1 you can try:
value = abs(value - 1);
MWE in C:
#include <stdio.h>
#include <stdlib.h>
int main()
{
printf("Hello, World!\n");
int value = 0;
int i;
for (i=0; i<10; i++)
{
value = abs(value -1);
printf("%d\n", value);
}
return 0;
}
Just because I like to question code. I propose that you can also make use of the ternary by doing something like this:
Example:
bool flipValue = false;
bool bShouldFlip = true;
flipValue = bShouldFlip ? !flipValue : flipValue;