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.

È stato utile?

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 a double
. - Altrimenti, se uno degli operandi è float, l'altro è convertito a float
. - 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 a unsigned long
. - Altrimenti, se un operando è long int e l'altra unsigned int, quindi se un long int può rappresentare tutti i valori di un unsigned int, il unsigned int è convertito in un long int; altrimenti entrambi gli operandi sono convertiti al unsigned long int.
- Altrimenti, se uno degli operandi è long, l'altro è convertito a long
. - Altrimenti, se uno degli operandi è unsigned, l'altro è convertito a unsigned.

[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 o unsigned short intcan essere convertito in un rvalue di tipo int se int può rappresentare tutti i valori del tipo di sorgente; altrimenti, il rvalue sorgente può essere convertito in un rvalue di tipo unsigned 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 o unsigned long.

3 Un rvalue per un campo di bit integrale (9.6) può essere convertito in un rvalue di tipo int se int può rappresentare tutti i valori del campo di bit; altrimenti, esso può essere convertito in unsigned int se unsigned 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 tipo int, con false diventa zero e true diventando one.

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

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top