2013-01-19 16 views
7

GCC (4.7.2) con -Wextra segnala il seguente avviso/errore (ho -Werror abilitato):“Attenzione: il confronto è sempre vero”

Il confronto è sempre vero a causa della limitata gamma del tipo di dati [ -Wtype-limits]

per il seguente codice [try online]:

template < 
    typename T, 
    std::size_t N, 
    bool = static_cast<std::size_t>(std::numeric_limits<T>::max()) < N> 
struct validator { 
    static constexpr bool validate(T value) { 
     return static_cast<std::size_t>(value) < N; 
    } 
}; 

template <typename T, std::size_t N> 
struct validator<T, N, true> { 
    static constexpr bool validate(T) { 
     return true; 
    } 
}; 

int main() { 
    // Works 
    static_assert(validator<int, 4>::validate(3), "Invalid"); 
    // Error :-(
    static_assert(validator<bool, 2>::validate(true), "Invalid"); 
} 

capisco perché l'avviso si sarebbe verificato in un contesto di espressione ormale, ad es. quando avrei usato il validate seguente funzione:

template <typename T, std::size_t N> 
bool validate(T value) { 
    return static_cast<std::size_t>(value) < N; 
} 

- In realtà, è per questo che sto usando il modello di specializzazione, in primo luogo (e si noti che il modello corretto di specializzazione viene utilizzato, e l'errore nel mio primo il codice viene generato dall'argomento del modello, non all'interno della funzione nel modello non specificato). C'è un modo per aggirare questo avvertimento? Se no, non è un bug nel compilatore?

+0

Suppongo che si possa aggirare il problema specializzando l'intera classe per situazioni in cui 'N' supera il valore massimo di' T' e ha 'validate' return' true'. –

+0

Penso che il bool sia 0 o 1, quindi tutti i bool sono minori di 2. – flup

+0

Il mio gcc 4.7.2-2 non ha avvisato quando ho provato questo, anche se forse ho usato gli include sbagliati. – Neil

risposta

11

Questo è stato risolto in tronco GCC, vedi PR 11856

in modo da attendere per circa la fine di aprile e utilizzare GCC 4.8 :-)

2

Dal momento che non posso aspettare fino a quando questo è fisso (vedi risposta di Jonathan) ho selettivamente disattivato l'avviso utilizzando GCC #pragma estensioni:

#pragma GCC diagnostic push 
#pragma GCC diagnostic ignored "-Wtype-limits" 
static_assert(validator<bool, 2>::validate(true), "Invalid"); 
#pragma GCC diagnostic pop 

Si noti che questi pragma purtroppo hanno bisogno di circondare il codice dichiamando anche thoug h l'errore effettivo si verifica nel parametro template.

1

Ecco una soluzione:

template < 
    typename T, 
    std::size_t N, 
    bool = static_cast<std::size_t>(std::numeric_limits<T>::max()) < N> 
struct validator { 
    static constexpr bool validate(T value) { 
     return size_t_cast(value) < N; 
    } 
private: 
    static constexpr std::size_t size_t_cast(T value) { 
     return value; 
    } 
}; 

template <typename T, std::size_t N> 
struct validator<T, N, true> { 
    static constexpr bool validate(T) { 
     return true; 
    } 
}; 

In questo modo l'esempio di compilare senza errori nel GCC 4.7.2.

+0

No, questo è equivalente al mio codice e ha lo stesso avviso (hai dimenticato di abilitare '-Wextra'!) Nota che, come ho detto nella domanda, l'avviso non è prodotto dal corpo della funzione - è prodotto dal modello istanziazione. Ciò che funziona, d'altra parte, sta definendo 'size_t_cast' al di fuori della struttura e quindi usandolo nell'elenco dei modelli. O, in effetti, senza l'intera struttura che è ora ridondante. –

+0

@KonradRudolph Se si nota, ho postato questa risposta dopo che mi è stato indicato che avevo dimenticato '-Wextra', e l'ho provato con' -Wextra -Werror'. – Neil

+0

In tal caso, prova di nuovo. Il tuo codice * fa * crea lo stesso avvertimento. –

Problemi correlati