avisos do compilador
-
21-08-2019 - |
Pergunta
Suponha que eu tenho isso (C ++ ou talvez C) código:
vector<int> my_vector;
for (int i = 0; i < my_vector.size(); i++) {
my_vector[i] = 0;
}
Eu não me importo se for feito direito. A parte importante é na declaração for-loop.
O compilador dá uma incompatibilidade assinado / sem assinatura para isso, já size () retorna um inteiro sem sinal, não uma assinado. Como é que é importante para mudar i
para não assinado? Declaro contadores de loop como ints por hábito, mas se isso é um erro potencial vou me forçar a sair do hábito.
Solução
Eu diria que é muito importante - você deve estar compilando com avisos como erros, e se esforçam para corrigir todos os avisos. Se você deixar problemas como este no seu código, é fácil entrar em um hábito de ignorar os avisos, ou deixar falsos positivos como este abafar os avisos que indicam problemas reais.
Neste caso, para este erro específico, provavelmente não é um grande negócio - em uma plataforma de 32 bits, você teria que ter mais de 2 bilhões de entradas no vetor antes da unsigned envolveria em um valor negativo assinado. Para obter um vector como este esgotaria toda a sua memória, por isso provavelmente não é possível entrar em um estado onde assinado / sem assinatura incompatibilidade teria importância.
Outras dicas
Tecnicamente, i
deve ser um vector<int>::size_type
. Você deve adquirir o hábito de usar typedef
s em seu código:
typedef vector<int> VectorType;
VectorType my_vector;
for (VectorType::size_type i = 0; i < my_vector.size(); i++) {
my_vector[i] = 0;
}
Agora, se nós alterá-lo para um deque
, só mudar uma linha. Mesmo que seja algum recipiente personalizado que tem um size_type maluco, você começa a quente, macio sensação de que tudo estará ok. E isso vale muito. Mesmo com apenas unsigned / assinado, há algumas questões de promoção complicadas com o uso assinado conversão / não assinado que, inevitavelmente, voltar a morder-lhe.
Isso pode ser importante no caso improvável de que o tamanho do vetor excede INT_MAX
. Se o tamanho do vetor é maior do que o valor máximo que pode ser representado em uma int
assinado, em seguida, o loop nunca terminará.
Bem, seus importante porque inteiros assinados têm sinal, para que eu pudesse ir todo o caminho até se tornar um valor negativo, então não importa o quão grande ele é, ele ainda seria menor do que o tamanho (), que não tenha um qualquer sinal.
11111111 <10000000
Na maioria dos casos de seu exemplo, ele não importa. mas quando o programa não funcionar, a primeira coisa que você faz (ou deveria) é certificar-se não há advertências, por isso é uma chance não vale a pena correr.
Certifique-se há tão poucas advertências quanto possível.
Como dito acima, o uso vector :: size_type; ou usar um iterador para loop através de seu vetor. Certifique-se de lidar com todos os seus próprios avisos como erros.