2014-10-06 13 views
14

Perché non è il compilatore lamentarsi di questo codice:Assegna il doppio a std :: string - nessun errore di compilazione?

#include <string> 
#include <iostream> 

int main() 
{ 
    std::string a; 
    a = 2.3; 
    std::cout << "A:" << a << std::endl; 
    return 0; 
} 

GCC, MSVC non sembrano essere preoccupati per questo a tutti, anche se è chiaramente sbagliata e in realtà non funziona comunque!

L'output è:

A: 

OUCH! Portare a un errore non rilevato nel mio programma.

+15

Attivare gli avvisi? Clang emette quanto segue: 'warning: la conversione implicita da 'double' a 'char' cambia valore da 2.Da 3 a 2 [-Wliteral-conversion] ' – Rapptz

+5

Sta facendo ciò che gli hai detto. Cambia il doppio valore in 65.3 e uscirà con 'A: A' (65 è il valore ASCII della lettera' A'). – Blastfurnace

+3

Nel mio GCC (4.82) anche '-Wall -Wextra' non attiva questo avviso su' -Wconversion' necessario. – Galik

risposta

10

std::string ha un sovraccarico per operator= che accetta un carattere. Quando si passa un argomento a una funzione in base al valore (cioè un operatore), si verifica copy initialization. Nell'inizializzazione della copia, standard conversions, nota anche come "conversione implicita", può essere utilizzata per convertire il valore. In questo caso, il tuo doppio viene convertito automaticamente in un carattere in modo che possa essere utilizzato in operator=.

Per GCC, -Wall -Wextra -pedantic non viene visualizzata alcuna diagnostica. Puoi provare -Wfloat-conversion, che è abilitato da -Wconversion. Esempio:

main.cpp:11:10: warning: conversion to 'char' alters 'double' constant value 
[-Wfloat-conversion] 
     a = 3.2; 

In alternativa, utilizzare le parentesi per forzare un errore di conversione restringimento.

s = {4.3}; 
// warning: narrowing conversion of '4.2e+1' from 'double' to 'char' inside { } 
// [-Wnarrowing] 
+0

Gli autori di std :: string potrebbero non aver reso esplicito questo costruttore 'mi chiedo? –

+1

Dato che "cast" è "conversione esplicita", "cast implicito" in realtà non ha molto senso, e la pagina a cui ti colleghi ha smesso di chiamarla al di fuori dell'URL nel 2012. – hvd

+1

@TT non è coinvolto alcun costruttore. La conversione implicita va da 'double' a' char'. –

6

Il compilatore esegue una conversione implicita da 2 al carattere ASCII equivalente: "start of text" (quindi non è possibile visualizzare nulla).

Forse hai disabilitato l'avviso del tuo compilatore. Prova a accenderli.

4

GCC:

compilazione in gcc con l'opzione [-Wconversion], allora vedrete che il compilatore emetterà l'avviso:

warning: conversion to 'char' alters 'double' constant value [-Wfloat-conversion]

LIVE DEMO

MSVC non sembrano di essere preoccupato per questo a tutti:

VS2013 produce il seguente avviso:

warning C4244: 'argument' : conversion from 'double' to 'char', possible loss of data

anche se è chiaramente sbagliata e in realtà non funziona comunque!

Non è sbagliato, è solo una conversione implicita dal tronco double 2.3 a un char con codice ASCII 2 (start of text).

+1

Sfortunatamente GCC con '-Wconversion' produce molti più avvisi del necessario, ad esempio per il codice' short x = 0; x + = 10; '. –

+3

'-Wconversion' abilita' -Wfloat-conversion'. Per evitare il problema menzionato da @Anton, basta '-Wfloat-conversion'. –

+0

Quindi a = 2.0 non darebbe quell'errore (perché il valore non è stato alterato)? È un peccato. – gnasher729

Problemi correlati