"goto"-Anweisung auch entgegengesetzt?
-
Original erstellt von Shade Of Mine:
**nein!
lies den Thread!!!Performance hat damit nix zu tun!
die meisten gotos werden einfach aus faulheit heraus gesetzt.
aber es gibt fälle wo goto sinnvoll sein kann - nämlich dann wenn goto das problem besser ausdrückt!sicher, man kann es mit immer umgehen - aber nicht immer ist der workaround besser als das goto.
zur performance:
ein goto zaubert auch nicht. ein break oder continue sind exakt gleichschnell wie ein goto - und sollte man inline funktionen verwenden (siehe volkard) dann ist das return auch genauso schnell!fazit: goto ist kein performance wunder!**
mmh
Ich sagte nicht das goto ein Performance Wunder ist. Und das es nicht schneller ist als break, exit, return oder so, is mir schon klar, aber das meinte ich auch nicht.
Ich hatte durchaus schon Konstukte (leider kein Beispiel zur Hand), bei denen ich nicht ein break, exit, return durch eine goto ersetzten würde, sondern wo ein komplexes Gebilde aus if's for's etc. durch goto's um einige Statusvaribalen und einigen Gebilden erleichtert werden konnte. Sowas is mir aber auch erst ein oder zweilmal begegenet, und ich lass auch da dann lieber die großen Gebilde stehen, weil es übersichtlicher ist!
Grüß Flow
-
Original erstellt von Flow_cplus:
**ich nicht ein break, exit, return durch eine goto ersetzten würde, sondern wo ein komplexes Gebilde aus if's for's etc. durch goto's um einige Statusvaribalen und einigen Gebilden erleichtert werden konnte. Sowas is mir aber auch erst ein oder zweilmal begegenet, und ich lass auch da dann lieber die großen Gebilde stehen, weil es übersichtlicher ist!
**muß ich zunächst öffetlich ablehnen.
hab hin und wieder gesehen, daß goto verwendet wurde, obwohl es ne ebensoschnelle und leichter zu lesende variante gab.test:
Ich durchsuche
C:\Programme\Microsoft Visual Studio\VC98\MFC\*.cpp
nach goto.Treffer in 22 Dateien.
in der dbflt.cpp das erste auftreten, was nich einfach goto error; ist.
void AFXAPI RFX_Double(CFieldExchange* pFX, LPCTSTR szName, double& value) { ASSERT(AfxIsValidAddress(pFX, sizeof(CFieldExchange))); ASSERT(AfxIsValidString(szName)); UINT nField; if (!pFX->IsFieldType(&nField)) return; LONG* plLength = pFX->m_prs->GetFieldLengthBuffer(nField - 1, pFX->m_nFieldType); switch (pFX->m_nOperation) { case CFieldExchange::BindFieldToColumn: { #ifdef _DEBUG // Assumes all bound fields BEFORE unbound fields CODBCFieldInfo* pODBCInfo = &pFX->m_prs->m_rgODBCFieldInfos[nField - 1]; if (pODBCInfo->m_nSQLType != SQL_C_DOUBLE && pODBCInfo->m_nSQLType != SQL_FLOAT) { // Warn of possible field schema mismatch if (afxTraceFlags & traceDatabase) TRACE1("Warning: double converted from SQL type %ld.\n", pODBCInfo->m_nSQLType); } #endif } // fall through default: LDefault: pFX->Default(szName, &value, plLength, SQL_C_DOUBLE, sizeof(value), 22); return; case CFieldExchange::Fixup: if (*plLength == SQL_NULL_DATA) { pFX->m_prs->SetNullFieldStatus(nField - 1); value = afxDoublePseudoNull; } return; case CFieldExchange::SetFieldNull: if ((pFX->m_pvField == NULL && pFX->m_nFieldType == CFieldExchange::outputColumn) || pFX->m_pvField == &value) { if (pFX->m_bField) { pFX->m_prs->SetNullFieldStatus(nField - 1); value = afxDoublePseudoNull; *plLength = SQL_NULL_DATA; } else { pFX->m_prs->ClearNullFieldStatus(nField - 1); *plLength = sizeof(value); } #ifdef _DEBUG pFX->m_nFieldFound = nField; #endif } return; case CFieldExchange::MarkForAddNew: // can force writing of psuedo-null value (as a non-null) by setting field dirty if (value != afxDoublePseudoNull) { pFX->m_prs->SetDirtyFieldStatus(nField - 1); pFX->m_prs->ClearNullFieldStatus(nField - 1); } return; case CFieldExchange::MarkForUpdate: if (value != afxDoublePseudoNull) pFX->m_prs->ClearNullFieldStatus(nField - 1); goto LDefault; case CFieldExchange::AllocCache: { CFieldInfo* pInfo = &pFX->m_prs->m_rgFieldInfos[nField - 1]; pInfo->m_pvDataCache = new double; pInfo->m_nDataType = AFX_RFX_DOUBLE; } return; #ifdef _DEBUG case CFieldExchange::DumpField: { *pFX->m_pdcDump << "\n" << szName << " = " << value; } return; #endif //_DEBUG } }
also das // fall through ist nix anderes als goto LDefault;
und dann haben alle fälle entweder return oder goto LDefault; am ende.
warum nicht den code von LDefault hinter das ganze switch-konstrukt basteln, bei default: nix machen, statt goto LDefault break machen und return return sein lassen?mal weitersuchen. lauter goto error, goto CleanUp und noch 10 bezeichener.
ah, occdlg.cpp:AFX_STATIC CWnd* AFXAPI _AfxNextControl(CWnd* pWndRoot, CWnd* pWndStart, UINT uFlags) { // if pWndStart is already equal to pWndRoot, this confuses this function // badly. ASSERT(pWndRoot != pWndStart); if (pWndStart == NULL) { FirstChild: pWndStart = pWndRoot->GetTopWindow(); if (pWndStart == NULL) return pWndRoot; goto Found; } else { // Are we at the last control within some parent? If so, pop back up. while (pWndStart->GetNextWindow() == NULL) { // Popup to previous real ancestor. pWndStart will be NULL, // pWndRoot, or the child of a recursive dialog. pWndStart = _AfxGetChildControl(pWndRoot, pWndStart->GetParent()); if ((pWndStart == NULL) || (pWndStart == pWndRoot)) { goto FirstChild; } } ASSERT(pWndStart != NULL); pWndStart = pWndStart->GetNextWindow(); } Found: if (IsControlParent(pWndStart)) { if (((uFlags & CWP_SKIPINVISIBLE) && !pWndStart->IsWindowVisible()) || ((uFlags & CWP_SKIPDISABLED) && !pWndStart->IsWindowEnabled())) pWndStart = _AfxNextControl(pWndRoot, pWndStart, uFlags); else pWndStart = _AfxNextControl(pWndStart, NULL, uFlags); } return pWndStart; }
Ist das nicht ne Meisterleistung?
Zweifellos gute kernel-hacker am werk. allein, wie elegant hier mit goto FirstChild; doppelter code gespart wird.
ok, das beispiel für gutes goto ist gefunden. (hrhr)
-
Ich erkenne mein Code wieder. Danke für das Kompliment
-
ich kann da wohl 5 zeilen sparen und auch alle bis auf ein goto wegmachen ohne performanceverlust. gehen auch alle gotos weg?
-
Es gehen alle Gotos wech. Nur warum willst Du sie rausnehmen?
-
Original erstellt von <KH>:
Es gehen alle Gotos wech. Nur warum willst Du sie rausnehmen?weils ja sein könnte, daß äqivalenter gode wie der hier
AFX_STATIC CWnd* AFXAPI _AfxNextControl(CWnd* pWndRoot, CWnd* pWndStart, UINT uFlags) { ASSERT(pWndRoot != pWndStart); for(;;) { if(pWndStart == NULL || pWndStart == pWndRoot) { pWndStart = pWndRoot->GetTopWindow(); if (pWndStart == NULL) return pWndRoot; break; } if(pWndStart->GetNextWindow() != NULL) { pWndStart = pWndStart->GetNextWindow(); break; } pWndStart = _AfxGetChildControl(pWndRoot, pWndStart->GetParent()); ASSERT(pWndStart != NULL); } if (!IsControlParent(pWndStart)) return pWndStart; if (((uFlags & CWP_SKIPINVISIBLE) && !pWndStart->IsWindowVisible()) || ((uFlags & CWP_SKIPDISABLED) && !pWndStart->IsWindowEnabled())) return _AfxNextControl(pWndRoot, pWndStart, uFlags); else return _AfxNextControl(pWndStart, NULL, uFlags); }
nicht lahmer wäre. und kleiner. und leichter zu lesen. dann wäre die verwendung von goto nur auf die schlampigkeit oder unerfahrenheit des rogrammierers oder termindruck zurückzuführen.
-
Naja, du kannst sie alle rausnhemen, aber es wird Dir halt nicht viel bringen.
-
Original erstellt von <KH>:
Naja, du kannst sie alle rausnhemen, aber es wird Dir halt nicht viel bringen.lies den thread von anfang an.
-
Nagut.
Wenn Du Hilfe brauchst, kannst ja bescheid sagen.
-
ist doch schon gelöst.