Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 12
  1. #1
    Utente di HTML.it L'avatar di hfish
    Registrato dal
    Dec 2000
    Messaggi
    3,180

    [C] piccolo indovinello

    codice:
    int array[] = { 23, 34, 12, 17, 204, 99, 16 };
    #define TOTAL_ELEMENTS (sizeof(array) / sizeof(array[0]))
    
    int main()
    {
    int d= -1, x;
    if (d <= TOTAL_ELEMENTS-2)
    x = array[d+1];
    return 0;
    }
    quanto vale x?
    a spanne avrei detto 23, invece torna 0, ovvero -1 + 1 anzichè andare a prendere l'elemento dell'array in posizione 0...

    ho la febbre e la mente non lucida, ma non mi torna e vorrei capire il perchè
    Non dobbiamo trascurare la probabilità che il costante inculcare la credenza in Dio nelle menti dei bambini possa produrre un effetto così forte e duraturo sui loro cervelli non ancora completamente sviluppati, da diventare per loro tanto difficile sbarazzarsene, quanto per una scimmia disfarsi della sua istintiva paura o ripugnanza del serpente.

  2. #2
    Il programma non entra nell'if, per cui x rimane non inizializzato e ti becchi qualunque valore rimasto sullo stack in quel momento.

    Ora: perché non entra nell'if? Se provi a compilare con i warning impostati a livello "relativamente alto" otterrai un messaggio di questo genere:
    codice:
    unsigned.c: In function ‘main’:
    unsigned.c:9:11: warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
    riferito alla riga
    codice:
    if (d <= TOTAL_ELEMENTS-2)
    E il problema è tutto qui: TOTAL_ELEMENTS è sizeof(array)/sizeof(array[0]), e sizeof restituisce un intero senza segno (nello specifico, un size_t); TOTAL_ELEMENTS-2, dunque, è ancora unsigned. d, invece, è un intero con segno, da cui il warning.

    Gli operatori relazionali, infatti, si aspettano di operare su interi del medesimo tipo, e, per raggiungere questa situazione, entrano in gioco le conversioni implicite, descritte a §6.3.1 dello standard C99; non sto a riportare qui tutte le regole, il punto chiave comunque è che
    If an int can represent all values of the original type, the value is converted to an int; otherwise, it is converted to an unsigned int.
    (§6.3.1.1 ¶2)
    Dato che un int non può rappresentare tutto il range di valori di un unsigned int, è lui ad essere convertito ad unsigned int, e non viceversa.

    Se d fosse positivo, questo non darebbe alcun problema; tuttavia, d è negativo, e la conversione di un int negativo in un unsigned int avviene come specificato a §6.3.1.3 ¶2:
    Otherwise, if the new type is unsigned, the value is converted by repeatedly adding or subtracting one more than the maximum value that can be represented in the new type until the value is in the range of the new type.
    il che in pratica significa che, ai fini della tua espressione, al posto di d avrai un intero senza segno enorme (UINT_MAX-1), che ovviamente è maggiore di TOTAL_ELEMENTS-2.

    Per risolvere, ti basta aggiungere un cast esplicito a int prima di TOTAL_ELEMENTS-2
    codice:
    if (d <= (int)(TOTAL_ELEMENTS-2))
    forzando così il confronto tra interi con segno, che dà il risultato previsto.
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Premesso che tutto è corretto, a questo punto ...

    codice:
    #define TOTAL_ELEMENTS ((int)(sizeof(array) / sizeof(array[0])))
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  4. #4
    Utente di HTML.it L'avatar di hfish
    Registrato dal
    Dec 2000
    Messaggi
    3,180
    Originariamente inviato da MItaly
    Il programma non entra nell'if, per cui x rimane non inizializzato e ti becchi qualunque valore rimasto sullo stack in quel momento.
    grazie per la risposta

    ni, il programma NON entra nell'if ma mi torna sempre 0... la cosa mi disturba
    Non dobbiamo trascurare la probabilità che il costante inculcare la credenza in Dio nelle menti dei bambini possa produrre un effetto così forte e duraturo sui loro cervelli non ancora completamente sviluppati, da diventare per loro tanto difficile sbarazzarsene, quanto per una scimmia disfarsi della sua istintiva paura o ripugnanza del serpente.

  5. #5
    Utente di HTML.it L'avatar di Scara95
    Registrato dal
    Jul 2009
    residenza
    Zimella (VR)
    Messaggi
    2,589
    Originariamente inviato da hfish
    grazie per la risposta

    ni, il programma NON entra nell'if ma mi torna sempre 0... la cosa mi disturba
    Magari dipende dal compilatore...
    http://ideone.com/rCP0wE
    "Quid enim est, quod contra vim sine vi fieri possit?" - Cicerone, Ad Familiares

  6. #6
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Che vuol dire "non entra nella if" ?

    Con quale codice? Hai seguito la spiegazione e apportato la modifica ?
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  7. #7
    Utente di HTML.it L'avatar di hfish
    Registrato dal
    Dec 2000
    Messaggi
    3,180
    Originariamente inviato da oregon
    Che vuol dire "non entra nella if" ?

    Con quale codice? Hai seguito la spiegazione e apportato la modifica ?
    con il cast esplicito sono abbastanza convinto che il tutto funzioni egregiamente, ma non sono in grado di testarlo ora.
    con il codice originale postato da me però x vale sempre 0 (almeno con il mio compilatore)

    codice:
    Using built-in specs.
    COLLECT_GCC=gcc
    COLLECT_LTO_WRAPPER=/usr/lib/gcc/x86_64-linux-gnu/4.7/lto-wrapper
    Target: x86_64-linux-gnu
    Configured with: ../src/configure -v --with-pkgversion='Debian 4.7.2-5' --with-bugurl=file:///usr/share/doc/gcc-4.7/README.Bugs --enable-languages=c,c++,go,fortran,objc,obj-c++ --prefix=/usr --program-suffix=-4.7 --enable-shared --enable-linker-build-id --with-system-zlib --libexecdir=/usr/lib --without-included-gettext --enable-threads=posix --with-gxx-include-dir=/usr/include/c++/4.7 --libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu --enable-libstdcxx-debug --enable-libstdcxx-time=yes --enable-gnu-unique-object --enable-plugin --enable-objc-gc --with-arch-32=i586 --with-tune=generic --enable-checking=release --build=x86_64-linux-gnu --host=x86_64-linux-gnu --target=x86_64-linux-gnu
    Thread model: posix
    gcc version 4.7.2 (Debian 4.7.2-5)
    Non dobbiamo trascurare la probabilità che il costante inculcare la credenza in Dio nelle menti dei bambini possa produrre un effetto così forte e duraturo sui loro cervelli non ancora completamente sviluppati, da diventare per loro tanto difficile sbarazzarsene, quanto per una scimmia disfarsi della sua istintiva paura o ripugnanza del serpente.

  8. #8
    Utente di HTML.it L'avatar di oregon
    Registrato dal
    Jul 2005
    residenza
    Roma
    Messaggi
    36,480
    Originariamente inviato da hfish
    con il codice originale postato da me però x vale sempre 0 (almeno con il mio compilatore)
    E quindi ?
    No MP tecnici (non rispondo nemmeno!), usa il forum.

  9. #9
    Utente di HTML.it L'avatar di hfish
    Registrato dal
    Dec 2000
    Messaggi
    3,180
    quindi non dovrebbe, visto che x rimane non inizializzata...
    Non dobbiamo trascurare la probabilità che il costante inculcare la credenza in Dio nelle menti dei bambini possa produrre un effetto così forte e duraturo sui loro cervelli non ancora completamente sviluppati, da diventare per loro tanto difficile sbarazzarsene, quanto per una scimmia disfarsi della sua istintiva paura o ripugnanza del serpente.

  10. #10
    Utente di HTML.it L'avatar di Scara95
    Registrato dal
    Jul 2009
    residenza
    Zimella (VR)
    Messaggi
    2,589
    prova con la flag
    -std='c99'
    "Quid enim est, quod contra vim sine vi fieri possit?" - Cicerone, Ad Familiares

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 © 2025 vBulletin Solutions, Inc. All rights reserved.