Pagina 1 di 3 1 2 3 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 21
  1. #1
    Utente di HTML.it
    Registrato dal
    May 2008
    Messaggi
    475

    [C++] Confronto tra interi fallisce?

    Ragazzi non ho idea di cosa stia succedendo...

    In pratica io ho una funzione che lavora su una matrice quadrata. Se la riga o la colonna sono più grandi della dimensione della matrice deve sollevare un'eccezione. Così:

    codice:
    square_matrix square_matrix::suppress(unsigned int row, unsigned int column) const
    	throw (out_of_bounds_exception)
    {
    	cout << "Debug couts:" << endl;
    	cout << "In square_matrix::suppress(unsigned, unsigned)." << endl;
    	cout << "_dim = " << _dim << endl;
    	cout << "row = " << row << endl;
    	cout << "column = " << column << endl;
    	
    	if ( (row >= _dim) || (column >= _dim) )
    		throw out_of_bounds_exception();
    
            ...
    }
    Quando la chiamo dal main, così:

    codice:
    try
    {
    	square_matrix B = A.suppress(0,0);
    	B.print();
    }
    catch(out_of_bounds_exception& ex)
    {
    	cerr << "out_of_bounds_exception raised." << endl;
    }
    Ottengo questo output meraviglioso:

    codice:
    Debug couts:
    In square_matrix::suppress(unsigned, unsigned).
    _dim = 3
    row = 0
    column = 0
    out_of_bounds_exception raised.
    Cioè, ora, io ero convinto che (0 < 3)... no? I numeri in gioco sono tutti unsigned.
    Qualcuno ha idea di cosa stia succedendo?
    "Let him who has understanding reckon the number of the beast, for it is a human number.
    Its number is rw-rw-rw-."

  2. #2
    Utente di HTML.it
    Registrato dal
    May 2008
    Messaggi
    475
    Problema risolto...

    Era una domanda veramente stupida ^^

    In realtà veniva sollevata la stessa identica eccezione più in giù nel metodo, quindi risaliva lo stack e arrivava dove la intercettavo convinto che arrivasse da lì.
    "Let him who has understanding reckon the number of the beast, for it is a human number.
    Its number is rw-rw-rw-."

  3. #3
    no, non è una cosa stupida; evidentemente il tuo modello per lanciare eccezioni:
    codice:
    if ( (row >= _dim) || (column >= _dim) )
    		throw out_of_bounds_exception();
    ti ha fatto perdere tempo.

    Meglio sarebbe un qualcosa del tipo:
    codice:
    RuntimeAssert ((row >= _dim) || (column >= _dim));
    che in caso di fallimento "logghi" almeno __FILE__ e __LINE__ no?
    ;-)

    ad esempio:
    codice:
    #define RuntimeAssert(theAssertion) YourRuntimeAssertFunction((theAssertion), __FILE__, __LINE__)

  4. #4
    Utente di HTML.it
    Registrato dal
    May 2008
    Messaggi
    475
    Più che altro è che più in giù nel metodo c'è una chiamata che può generare la stessa eccezione, e non ho pensato a intercettare anche quella.

    L'idea di loggare file e linea mi sembra ottima, ma una volta risolto il problema vorrei di nuovo tornare alle eccezioni: questo perchè in sostanza quella funzione permette all'user di eliminare una riga e una colonna dalla matrice, ma come ben sai, tutto l'input è malvagio

    Cioè, se l'utente inserisce riga e colonna sbagliati, viene sollevata un'eccezione, gli do del cretino, e può riprovare... Se il programma termina loggando l'errore bisogna riavviarlo da capo
    "Let him who has understanding reckon the number of the beast, for it is a human number.
    Its number is rw-rw-rw-."

  5. #5
    codice:
    #define STRINGIFY(x) #x
    #define TOSTRING(x) STRINGIFY(x)
    #define ERROR_STD_PROLOG    "Exception thrown in function: " __FUNCSIG__ " (in " __FILE__ ", last modified on " __TIMESTAMP__ ", line " TOSTRING( __LINE__ ) ").\nMessage: "
    Quindi:
    codice:
    throw out_of_range(ERROR_STD_PROLOG "Panico e morte!");
    Occhio che aumenta un po' le dimensioni dell'eseguibile, dato che ogni messaggio (completo di signature della funzione, file e riga) viene salvato per i fatti suoi nella sezione stringhe dell'eseguibile. Ad un certo punto avevo fatto una classe eccezione più furba che memorizzava i pezzi separatamente, risparmiando un bel po' di spazio (tutti i vari __FILE__ e __TIMESTAMP__ dello stesso file vengono riciclati, e così pure i pezzi comuni a tutte le eccezioni), ma ora come ora non la trovo.

    In verità la cosa più comoda di tutte sarebbe poter avere uno stack trace, ma non esiste un modo standard multipiattaforma per recuperarlo; esistono però diverse librerie che vengono in aiuto, e vedo che stanno pensando a qualcosa del genere in boost - il che sarebbe assai figo .
    Amaro C++, il gusto pieno dell'undefined behavior.

  6. #6
    Utente di HTML.it
    Registrato dal
    May 2008
    Messaggi
    475
    Non capisco il senso della macro TOSTRING: non la si può semplicemente definire come

    codice:
    #define TOSTRING(x) #x
    ?
    "Let him who has understanding reckon the number of the beast, for it is a human number.
    Its number is rw-rw-rw-."

  7. #7
    No, perché, per come funziona l'espansione delle macro, se definissi TOSTRING in quella maniera otterresti
    "__LINE__", "__FILE__", eccetera. Il doppio passaggio è necessario perché le macro __LINE__, __FILE__ e compagnia vengano espanse nei loro effettivi valori prima di passare per l'operatore # che le rende stringhe ("65", "./test.cpp", ...).
    Amaro C++, il gusto pieno dell'undefined behavior.

  8. #8
    Utente di HTML.it
    Registrato dal
    May 2008
    Messaggi
    475
    Mmm, ho capito... più meno. brb testin'
    "Let him who has understanding reckon the number of the beast, for it is a human number.
    Its number is rw-rw-rw-."

  9. #9
    Utente di HTML.it
    Registrato dal
    May 2008
    Messaggi
    475
    Non funziona...

    Ad ogni uso da una serie di errori "expected primary expression before '(' token" e poi il corrispondente "expected ')' before __FUNCSIG__"...

    Eppure la macro mi sembra corretta
    "Let him who has understanding reckon the number of the beast, for it is a human number.
    Its number is rw-rw-rw-."

  10. #10
    Utente di HTML.it
    Registrato dal
    May 2008
    Messaggi
    475
    Ok, ho isolato il problema... se provo a fare:

    codice:
    throw exception( __FUNCSIG__ );
    mi dice che __FUNCSIG__ non è definita in questo scope...
    "Let him who has understanding reckon the number of the beast, for it is a human number.
    Its number is rw-rw-rw-."

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2024 vBulletin Solutions, Inc. All rights reserved.