L'aggiunta di due caratteri produce int
-
25-10-2019 - |
Domanda
Ho fatto un programma semplice e compilato con GCC 4.4 / 4.5 come segue:
int main ()
{
char u = 10;
char x = 'x';
char i = u + x;
return 0;
}
g ++ -c -Wconversion a.cpp
E ho ottenuto il seguente:
a.cpp: In function ‘int main()’:
a.cpp:5:16: warning: conversion to ‘char’ from ‘int’ may alter its value
Lo stesso avvertimento che ho per il seguente codice:
unsigned short u = 10;
unsigned short x = 0;
unsigned short i = u + x;
a.cpp: In function ‘int main()’:
a.cpp:5:16: warning: conversion to ‘short unsigned int’ from ‘int’ may alter its value
Qualcuno potrebbe spiegare il motivo per cui mi aggiunta di due caratteri (o due cortometraggi firmati) produce int? Si tratta di un bug del compilatore o è compatibile con standard di?
Grazie.
Soluzione
quello che stai vedendo è il risultato dei cosiddetti "conversioni aritmetiche abituali" che si verificano durante le espressioni aritmetiche, in particolare quelli che sono binari in natura (prendere due argomenti).
Questo è descritto in § 5/9:
Molti operatori binari che prevedono operandi di conversioni causano aritmetiche o tipo enumerazione e tipi di risultato resa in un modo simile. Lo scopo è quello di produrre un tipo comune, che è anche il tipo del risultato. Questo modello è chiamato conversioni aritmetiche abituali , che vengono definiti come segue:
- Se uno degli operandi è di tipo
long double
, l'altro deve essere convertito tolong double
. - Altrimenti, se uno degli operandi èdouble
, l'altro è convertito adouble
. - Altrimenti, se uno degli operandi èfloat
, l'altro è convertito afloat
. - In caso contrario, le promozioni integrali (4.5) devono essere eseguiti su entrambi gli operandi 54) . - Poi, se uno degli operandi èunsigned long
l'altro è convertito aunsigned long
. - Altrimenti, se un operando èlong int
e l'altraunsigned int
, quindi se unlong int
può rappresentare tutti i valori di ununsigned int
, ilunsigned int
è convertito in unlong int
; altrimenti entrambi gli operandi sono convertiti alunsigned long int
.
- Altrimenti, se uno degli operandi èlong
, l'altro è convertito along
. - Altrimenti, se uno degli operandi èunsigned
, l'altro è convertito aunsigned
.[Nota: in caso contrario, l'unico caso rimanente è che entrambi gli operandi sono
int
]
Le promozioni alluso in §4.5 sono:
1 Un rvalue di tipo
char
,signed char
,unsigned char
,short int
ounsigned short int
can essere convertito in un rvalue di tipoint
seint
può rappresentare tutti i valori del tipo di sorgente; altrimenti, il rvalue sorgente può essere convertito in un rvalue di tipounsigned int
.2 Un rvalue di tipo
wchar_t
(3.9.1) o un tipo di enumerazione (7.2) può essere convertito in un rvalue del primo dei seguenti tipi che possono rappresentare tutti i valori della sua tipo sottostante:int
,unsigned int
,long
ounsigned long
.3 Un rvalue per un campo di bit integrale (9.6) può essere convertito in un rvalue di tipo
int
seint
può rappresentare tutti i valori del campo di bit; altrimenti, esso può essere convertito inunsigned int
seunsigned int
può rappresentare tutti i valori del campo di bit. Se il bit-field è più grande ancora, nessuna promozione integrale si applica ad esso. Se il bit-field ha un tipo enumerato, viene trattato come qualsiasi altro valore di quel tipo per scopi di promozione.4 Un rvalue di tipo
bool
può essere convertito in un rvalue di tipoint
, confalse
diventa zero etrue
diventandoone
.5 Queste conversioni sono chiamati promozioni integrali.
Da qui, sezioni quali " Operatori moltiplicativi " o " operatori additivi " tutti hanno la frase: " I normali conversioni aritmetiche vengono eseguite ... " per specificare il tipo di espressione.
In altre parole, quando si esegue l'aritmetica integrante il tipo è determinato con le categorie di cui sopra. Nel tuo caso, la promozione è coperto da §4.5 / 1 e il tipo delle espressioni sono int
.
Altri suggerimenti
Quando si esegue un'operazione aritmetica del tipo char
, il risultato viene restituito è di tipo int
.
Vedere questo:
char c = 'A';
cout << sizeof(c) << endl;
cout << sizeof(+c) << endl;
cout << sizeof(-c) << endl;
cout << sizeof(c-c) << endl;
cout << sizeof(c+c) << endl;
Output:
1
4
4
4
4
Manifestazione a Ideone: http://www.ideone.com/jNTMm
quando si aggiungono questi due personaggi con l'altro vengono prima di essere promossi a int.
Il risultato di un'aggiunta è un rvalue che è implicitamente promosso tipo INT se necessario, e se un int può contenere il valore risultante. Questo è vero su qualsiasi piattaforma in cui sizeof (int)> sizeof (char). Ma attenzione al fatto che char potrebbe essere trattato come char firmato da il compilatore.
Questi link possono essere di ulteriore aiuto - wiki e securecoding