2016-05-18 27 views
12

Perché non viene visualizzato un errore durante il tentativo di creare un array di dimensioni negative?Nessun errore per array di dimensioni negative

#include <array> 

int main() 
{ 
    std::array<int, -1> arr; 
} 

Con -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC Non ottengo alcun errore. È questo comportamento previsto?

+2

quale compilatore si sta utilizzando? Ho usato gcc 5.3.1 e ho ottenuto l'errore 'la dimensione della variabile' arr 'è troppo grande' –

risposta

8

Tipo di std::array è:

template< 
    class T, 
    std::size_t N 
> struct array; 

quando si inizializza il parametro secondo modello con -1, è implicitamente convertito in un valore molto grande come std::size_t è unsigned (che è illegale in C++ come sottolineato dal other answer e dovrebbe essere diagnosticato).

Un'altra possibilità è che il tuo arr sia ottimizzato. È possibile confermare questo aggiungendo il flag -fdump-tree-optimized alla riga di comando gcc.

Se si garantisce arr non è ottimizzato fuori, spero che si dovrebbe ottenere il following warning:

prog.cpp:5:25: error: size of variable 'arr' is too large 
    std::array<int, -1> arr; 
+1

L'ottimizzazione non si verifica dopo tali controlli di avviso? – BartoszKP

+1

@BartoszKP Ho usato 'gcc --std = C++ 11 -O2 -fdump-tree-ottimizzato arr_que.cpp' e ho confermato che il codice è ottimizzato per il solo' return 0; 'come ci si potrebbe aspettare. Non sono sicuro che sia necessario diagnosticare l'uso improprio dei parametri modello. –

19

No non è legale. Non c'è nulla riguardo alle specifiche di std::array che impedisce esplicitamente questo, ma è illegale a causa del restringimento delle conversioni.

§14.3.2/5:

Per un non-modello di tipo-parametro di tipo integrale o enumerazione, conversioni permessa in un'espressione costante convertito (5,19) sono applicati.

§5.19/3:

Un convertito costante espressione di tipo T è un letterale espressione costante, implicitamente convertito nel tipo T, in cui la conversione implicita (se presente) è consentita in un espressione costante letterale e la sequenza di conversione implicita contiene solo conversioni definite dall'utente, conversioni lvalue-rvalue (4.1), promozioni integrali (4.5) e conversioni integrali (4.7) diverse dal restringimento delle conversioni (8.5.4)

L'unico modo per ottenere da GCC di lamentarsi è abilitare -Wsign-conversion. Questo è un known bug e non hanno fatto alcun movimento per risolverlo.

In Clang si ottiene il messaggio di errore previsto:

error: non-type template argument evaluates to -1, which cannot be 
narrowed to type 'std::size_t' (aka 'unsigned long') [-Wc++11-narrowing] 
    std::array<int, -1> arr; 
+1

Nota storica: nel C++ 11 pubblicato era definito dall'implementazione se si trattava di una conversione a restringimento, ma questo era stato risolto dal DR 1449 per restringersi sempre –

Problemi correlati