#include <iostream>
#include <string>
#include <vector>
#include <sstream>
using namespace std;
int main() {
vector<double> vector_double;
vector<string> vector_string;
...
while (cin >> sample_string)
{
...
}
for(int i = 0; i <= vector_string.size(); i++)
{
....
}
for (int i = 0; i < vector_double.size(); i++)
....
return 0;
}
Respuesta
¿Por qué hay una advertencia con
-Wsign-compare
?
Como el nombre de la advertencia y su texto implican, el problema es que está comparando un entero con signo y sin signo. En general se supone que esto es un accidente.
Para evitar esta advertencia, simplemente necesita asegurarse de que ambos operandos de <
(o cualquier otro operador de comparación) estén firmados o no firmados.
¿Cómo podría hacerlo mejor?
La forma idiomática de escribir un bucle for
es inicializar tanto el contador y el límite en la primera declaración:
for (std::size_t i = 0, max = vec.size(); i != max; ++i)
Esto ahorra recomputing size()
en cada iteración.
También podría (y probablemente debería) utiliza iteradores en lugar de índices:
for (auto it = vec.begin(), end = vec.end(); it != end; ++it)
auto
aquí es una forma abreviada de std::vector<int>::iterator
. Los iteradores funcionan para cualquier tipo de contenedor, mientras que los índices lo limitan a C-arrays, deque
y vector
.
esto funcionó. aunque max() no funcionó, lo cambié a max. gracias – code511788465541441
No utilizaría la forma máxima porque - dependiendo de su ciclo, el tamaño del vec puede cambiar, por lo que es más seguro comprobar siempre el tamaño real del vec. – inf
Inicializar el límite primero solo funciona si el contenedor no cambia de tamaño dentro del bucle. De lo contrario, declararía el límite como una variable 'const' antes del ciclo, para darle al compilador munición adicional contra los programadores que intentan cambiar la variable. –
La variable de i
es un entero mientras que la función size
miembro del vector que devuelve un Allocator::size_type
es más probable que devuelve un size_t
, que es casi siempre implementado como int sin firmar de algún tamaño.
Se debe a que la función .size() de la clase de vectores no es de tipo int, pero de tipo vector :: size_type
uso o que auto i = 0u
y los mensajes debe desaparecer.
El uso de auto aquí no funcionará, ya que el tipo deducido se firmaría int. Usando auto i = 0U; trabajos. –
@SR_ Así es, gracias arreglado. – inf
Haga su int i
como size_type i
.
std::vector::size()
devolverá size_type
que es unsigned int
ya que el tamaño no puede ser -ve.
La advertencia es obviamente porque está comparando un entero con signo con un entero sin signo.
contestador después de tantas respuestas, pero nadie tomó nota del final del bucle .. Por lo tanto, aquí está mi respuesta completa:
- Para eliminar la advertencia, cambiar el tipo del
i
's para serunsigned
,auto
(por C++ 11), ostd::vector<your_type>::size_type
- Sus bucles
for
se SEG-culpa, si se utiliza este índice comoi
- debe recorrer desde0
asize-1
, ambos inclusive. Por lo tanto, el cambio a ser
for(std::vector<your_type>::size_type i = 0; i < vector_xxx.size(); ++i)
(nótese el<
, no<=
; mi consejo no es para usar con<=
.begin() - 1
, porque puede tener un vector 0 tamaño y que se tener problemas con eso :)). - Para hacer esto más genérico, ya que estás usando un contenedor y estás iterando a través de él, puedes usar
iterator
s. Esto facilitará el cambio futuro del tipo de contenedor (si no necesita la posición exacta como número, por supuesto). Por tanto, os escribo de esta manera:
for(std::vector<your_type>::iterator iter = vector_XXX.begin();
iter != vector_XXX.end();
++iter)
{
//..
}
Recibirá esta advertencia porque el tamaño de un contenedor en C++ es de tipo sin signo y la mezcla de tipos con signo/sin firmar es peligrosa.
Lo que hago normalmente es
for (int i=0,n=v.size(); i<n; i++)
....
esto es en mi opinión la mejor manera de utilizar los índices porque el uso de un tipo sin signo de un índice (o el tamaño de un contenedor) es un error lógico.
Los tipos sin signo deben usarse solo cuando se preocupa por la representación de bit y cuando se va a usar el comportamiento modulo- (2 ** n) en overflow. El uso de tipos sin firmar solo porque un valor nunca es negativo es una tontería.
Un error típico de la utilización de los tipos sin signo para tamaños o índices es, por ejemplo
// Draw all lines between adjacent points
for (size_t i=0; i<pts.size()-1; i++)
drawLine(pts[i], pts[i+1]);
el código anterior es UB cuando el conjunto de puntos está vacío porque en C++ 0u-1
con es un número positivo enorme. El motivo por el cual C++ usa un tipo sin signo para el tamaño de contenedores es porque esa opción es un patrimonio histórico de computadoras de 16 bits (y la semántica de C++ con tipos sin signo de IMO era la opción incorrecta incluso en aquel entonces).
int
está firmado de manera predeterminada; es equivalente a escribir signed int
. La razón por la que recibe una advertencia es porque size()
devuelve un vector::size_type
que es más que probable que no esté firmado.
Esto tiene un peligro potencial ya que signed int
y unsigned int
tienen diferentes rangos de valores. signed int
puede contener valores entre –2147483648
a 2147483647
mientras que un unsigned int
puede contener valores entre 0
a 4294967295
(suponiendo que int
es de 32 bits).
Declarar 'size_t i' para mí funciona bien.
por lo general a resolver de esta manera:
for(int i = 0; i <= (int)vector_string.size(); i++)
que utilizan la conversión de estilo C porque es más corto y más fácil de leer que el C++ static_cast<int>()
, y consigue el mismo efecto.
Existe un potencial de desbordamiento aquí, pero solo si su tamaño de vector es mayor que el mayor int
, generalmente 2147483647. Nunca en mi vida tuve un vector tan grande. Si hay incluso una posibilidad remota de utilizar un vector más grande, una de las respuestas que sugiere size_type
sería más apropiada.
No me preocupo por llamar al size()
repetidamente en el bucle, ya que es probable que sea un acceso en línea a una variable miembro que no introduce gastos generales.
- 1. Una advertencia: comparación entre expresiones enteras con signo y sin signo
- 2. enteros sin signo en C++ para bucles
- 3. Diferencia entre i ++ y ++ i en un bucle for
- 4. iteración inversa no firmada con los bucles for
- 5. Diferencia entre int sin signo y sin signo en C++
- 6. ¿cuál es la diferencia entre i ++ y ++ i for for loop (Java)?
- 7. ¿Cómo puedo corregir advertencias como: "comparación entre firmado y sin firmar"?
- 8. problemas con bucles for en lambdas
- 9. evitar dos bucles en I
- 10. diferencia entre (++ i) y (i ++)
- 11. romper dos bucles for
- 12. Manejando adecuadamente la comparación de los valores con signo y sin signo
- 13. Rotura en bucles for anidados
- 14. diferencia entre ++ i y i ++
- 15. lotes bucles for anidados
- 16. UTF-8 y Unicode, ¿qué pasa con 0xC0 y 0x80?
- 17. Obtener cuenta de bucles dentro de un bucle FOR Python
- 18. Cómo paralelizar correctamente un bucles for anidados
- 19. Comparación y conversión enteras de String PHP String
- 20. ¿Qué pasa con este programa C
- 21. ¿Deberían preferirse los "bucles while" a los "bucles for" para bucles grandes y necesarios en R?
- 22. return statement in for bucles
- 23. diferencia entre int * i y int * i
- 24. Diferencia entre int * i y int ** i
- 25. ¿Qué pasa con DCOM?
- 26. ¿Qué pasa con la notación de expresiones regulares de JavaScript?
- 27. Números sin signo versus números con signo
- 28. Python combinan dos bucles for
- 29. Diferencia entre foreach y for bucles sobre una clase IEnumerable en C#
- 30. i = i ++ no incrementa i. ¿Por qué?
El error te dice exactamente qué es lo que está mal. Hay exactamente una operación de comparación por ciclo for, para que pueda ver qué se compara con qué. Puede ver que 'i' es de un tipo con signo (¡eligió el tipo!), Por lo que lógicamente implica que la otra expresión es de tipo sin signo. –
Posible duplicado de [¿Cómo puedo corregir advertencias como: "comparación entre firmado y sin firmar"?] (Http://stackoverflow.com/questions/859943/how-can-fix-warnings-like-comparison-between- firm-and-unsigned) –