Go Down

Topic: Probabile BUG del compilatore ... (Read 7616 times) previous topic - next topic

gpb01


Chiaro. Mi domando cosa e/o come hanno modificato il comportamento del compilatore in questi casi che una certa ambiguità la creano.


Bé ... i sorgenti di avr gcc dovrebbero essere disponibili ... buona lettura ... 

Guglielmo
Search is Your friend ... or I am Your enemy !

Maurotec

C++ è ISO standard ed è normale aspettarsi una evoluzione del C++.
https://isocpp.org/std/status

GCC ISO compliant, per cui c'è da vedere come e quando sarà fedele allo standard C++11, C++14 ecc, non è per niente un gioco da ragazzi.
Il comportamento evidenziato da gpb01 è tipico di C++98, c'è da vedere quale incarnazione di GCC usa Arduino, poi
non dimentichiamo che AVR-GCC segue un'altro standard detto Embedded C (almeno ci prova e quanto aderente sia non l'ho mai sondato) il quale non mi pare faccia riferimento a C++ quindi AVR-GCC si trova su due fronti diversi a seguire cosa?  ;)

Comunque mi sembra un problema risolvibile e la proposta di inserire un'altra funzione... io direi che due sono già superflue in ambito embedded.   :P

Ciao.



leo72


il secondo è 6 e quindi viene intepretato come int

E' quanto ho pensato anch'io ieri, facendo i test quando Guglielmo mi ha informato della cosa. Però suona strano perché un numero è una costante e come tale con che criterio viene scelto il tipo (u)int16 piuttosto che il tipo (u)int8?

nid69ita



il secondo è 6 e quindi viene intepretato come int

E' quanto ho pensato anch'io ieri, facendo i test quando Guglielmo mi ha informato della cosa. Però suona strano perché un numero è una costante e come tale con che criterio viene scelto il tipo (u)int16 piuttosto che il tipo (u)int8?

Premetto che non sò quali algoritmi un compilatore segua per decidere quale funzione overloaded scelga.
Credo che il problema principale non sia tanto sul 8 o 16. La cifra 6 è ambigua anche in questo caso perchè potrebbe essere considerata 16 o 8 e non ci sarebbero problemi.  Secondo me il vero dilemma è se considerarla signed o unsigned, nella lista di funzioni candidate è quella la vera discriminante per fare una scelta.
Per questo mi dicevo curioso di sapere chissà che algoritmi hanno implementato per queste scelte "quasi" intelligenti. Logico che non ho voglia di leggermi i sorgenti del gcc ne credo qualcuno abbia voglia di farlo.  :D
my name is IGOR, not AIGOR

leo72

Il problema non è se signed o unsigned. Perché sai fai il cast esplicito ad entrambi i tipi ad 8  oppure a 16 bit, il compilatore non dà errore perché giustamente ha già i 2 casi overloadati. Ma nel caso di un int8 e di un numero, con che criterio stabilisce che una COSTANTE NUMERICA è int16?

gpb01


Ma nel caso di un int8 e di un numero, con che criterio stabilisce che una COSTANTE NUMERICA è int16?


... mah ... io ho idea che semplicemente, QUALSIASI costante numerica, che non sia una long o una float, la prende sempre come int ;)

Guglielmo
Search is Your friend ... or I am Your enemy !

nid69ita

#21
Apr 14, 2014, 09:29 am Last Edit: Apr 14, 2014, 09:43 am by nid69ita Reason: 1


Ma nel caso di un int8 e di un numero, con che criterio stabilisce che una COSTANTE NUMERICA è int16?


... mah ... io ho idea che semplicemente, QUALSIASI costante numerica, che non sia una long o una float, la prende sempre come int ;)

Guglielmo

Secondo me anche. Quindi consigliano di usare i qualificatori letterali tipo UL per unsigned long.
Ma per costanti intere unsigned, c'e' un qualificatore letterale (forse basta U ?!? ) . Non me lo ricordo.  :smiley-red:
P.S. questo lo accetta      unsigned int led = 13U;
Quinto post: http://cboard.cprogramming.com/c-programming/98488-literal-ul.html
my name is IGOR, not AIGOR

leo72

Scusate, ma ricordo male oppure il tipo dati di riferimento normalmente in C è l'intero?
Se così fosse, torneremmo al mix di ANSI C  e Embedded C a cui faceva riferimento Mauro, ossia che avr-gcc sottosta a 2 standard diversi mescolando un pò da questo e un pò da quello.  :smiley-roll-blue:

testato

da quel che ho letto il tipo di riferimento e' sempre int, pero' in base al calcolatore usato int puo' significare cose diverse ed anche allineamenti diversi, su alcuni MSB e' il byte destro su altri e' il sinistro, almeno all'epoca dei PDP11, degli Zilog, ecc  :)
- [Guida] IDE - http://goo.gl/ln6glr
- [Lib] ST7032i LCD I2C - http://goo.gl/GNojT6
- [Lib] PCF8574+HD44780 LCD I2C - http://goo.gl/r7CstH

leo72

Forse ti confondi con l'architettura adottata, che di solito si riflette sul tipo dato base utilizzato. Cioè sulle macchine a 16 bit viene usato l'int16 perché così le operazioni sugli interi si svolgono in meno cicli.
Ora, gli Atmel hanno le CPU ad 8 bit però i registri interni sono a 16.

gpb01


Scusate, ma ricordo male oppure il tipo dati di riferimento normalmente in C è l'intero?


Si, ricordi bene, normalmente, se non specificato, si tratta di int :)



da quel che ho letto il tipo di riferimento e' sempre int, pero' in base al calcolatore usato int puo' significare cose diverse ed anche allineamenti diversi, su alcuni MSB e' il byte destro su altri e' il sinistro, almeno all'epoca dei PDP11, degli Zilog, ecc  :)


Come giustamente ti indica Leo ... quella è solo l'architettura interna ... big-endian o little-endian ... ;)

Guglielmo
Search is Your friend ... or I am Your enemy !

PaoloP


Maurotec


E vai col mal di testa.  :smiley-roll-blue:


Se volete scoprire come stanno le cose nel dettaglio il mal di testa non può che aumentare. ;)
GCC ha un nome e molte facce, diciamo incarnazioni. Se passo -std=gnu99 il compilatore incarna
la specifica gnu99 che è diversa da c99. A complicare la cosa GCC ha un altro compilatore separato con il suo
preprocessore e linker per il C++ e questo può incarnare le specifiche C++98, C++03, C++11, si ottiene ciò attraverso le flags.

Ora dovete trovare quale standard C++ usa Arduino 1.05 (oltre che la verisone) e quale standard C++ usa Arduino 1.5.xx, studiarvi entrambe gli standard e alla fine trarre le conclusioni. Io ho interesse a studiare lo standard Embeddec C, ma il costo del documento è alto per le mie tasche, per cui mi accontento dei Draft gratuiti, che però sono una anteprima dello standard Embedded C o almeno è così che li si deve considerare. Acquistando il documento definitivo che definisce le specifiche per quello standard si potrebbe anche scoprire che il/i draft erano sufficienti a documentarsi oppure no, ma appunto prima lo devi acquistare.

Anche AVR-GCC C++ 4.7.2 dovrebbe essere C++03 e C++11, dovrebbe perché non c'è alcun motivo per non esserlo, 
e quindi non ho certezza. Sicuramente per ciò che concerne il C di AVR-GCC c'è l'intensione di seguire lo standard Embedded C di cui ho letto solo i draft, per cui non so quanto presente nelle specifiche sia già implementato, ma ho certezza che sono al passo con i draft.

Per AVR-GCC C++ non c'è uno standard Embedded C++ da seguire, per cui lo standard è quello generico C++03 ecc che non sono specifici per embedded.

Ciao.

PaoloP


Ora dovete trovare quale standard C++ usa Arduino 1.05 (oltre che la verisone) e quale standard C++ usa Arduino 1.5.xx,


Per la 1.5.x è facile.
Basta vedere il file platform.txt --> https://github.com/arduino/Arduino/blob/ide-1.5.x/hardware/arduino/avr/platform.txt
Code: (platform.txt) [Select]
# Default "compiler.path" is correct, change only if you want to overidde the initial value
compiler.path={runtime.ide.path}/hardware/tools/avr/bin/
compiler.c.cmd=avr-gcc
compiler.c.flags=-c -g -Os -w -ffunction-sections -fdata-sections -MMD
compiler.c.elf.flags=-Os -Wl,--gc-sections
compiler.c.elf.cmd=avr-gcc
compiler.S.flags=-c -g -x assembler-with-cpp
compiler.cpp.cmd=avr-g++
compiler.cpp.flags=-c -g -Os -w -fno-exceptions -ffunction-sections -fdata-sections -MMD
compiler.ar.cmd=avr-ar
compiler.ar.flags=rcs
compiler.objcopy.cmd=avr-objcopy
compiler.objcopy.eep.flags=-O ihex -j .eeprom --set-section-flags=.eeprom=alloc,load --no-change-warnings --change-section-lma .eeprom=0
compiler.elf2hex.flags=-O ihex -R .eeprom
compiler.elf2hex.cmd=avr-objcopy
compiler.ldflags=
compiler.size.cmd=avr-size

# This can be overriden in boards.txt
build.extra_flags=

# These can be overridden in platform.local.txt
compiler.c.extra_flags=
compiler.c.elf.extra_flags=
compiler.S.extra_flags=
compiler.cpp.extra_flags=
compiler.ar.extra_flags=
compiler.objcopy.eep.extra_flags=
compiler.elf2hex.extra_flags=

siccome non vedo nessun flag -std ne deduco che usi quello di default di avr-gcc.
Per la 1.0.x non so dove cercare perché hardcodato nell'IDE.

Maurotec

Vedo il mal di testa non ti spaventa a me si invece.
La trama si infittisce, entrambe i compilatori incarnano di default le specifiche C++98 e questo è già
sufficiente a creare il mal di testa, se poi ci aggiungi quello evidenziato è un comportamento documentato nei libri C++ ed è tipico di C++98.... a quali conclusioni si arriva; gcc-4.8.1 non si comporta come C++98 o forse si, perché ci sono delle ammended del 2003 che dovrebbero essere...uff uff, leggi qua:

Quote

The original ISO C++ standard was published as the ISO standard (ISO/IEC 14882:1998) and amended by a Technical Corrigenda published in 2003 (ISO/IEC 14882:2003). These standards are referred to as C++98 and C++03, respectively. GCC implements the majority of C++98 (export is a notable exception) and most of the changes in C++03. To select this standard in GCC, use one of the options -ansi, -std=c++98, or -std=c++03; to obtain all the diagnostics required by the standard, you should also specify -pedantic (or -pedantic-errors if you want them to be errors rather than warnings).


()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()()

Ciao.

Go Up