tipos sintaxis pero los identificar gramaticales errores ejecuta dev compila como c++ runtime-error

sintaxis - Los errores más difíciles de encontrar en c++



errores de sintaxis en c++ (8)

Clásico:

#define if while #define else

enterrado en algún encabezado.

Jamming en el comentario de @ WhozCraig, también:

#define true (!!(__LINE__ % 10))

Una vez cada diez líneas, la true no será tan true , pero el comportamiento del programa compilado permanecerá consistente ... para cambiar inexplicablemente cuando algo cambie en las fuentes.

En esta línea:

#define for if(__LINE__ % 10) for #define NULL (!(__LINE__ % 10))

O ¿qué pasa con:

#define virtual

esto causará serios problemas, pero solo cuando se utiliza el envío dinámico, lo que puede hacer que su detección sea mucho más problemática.

De una forma similar:

#define dynamic_cast static_cast

// Fail early, fail often #define throw std::abort();

Soy consciente de que probablemente no haya "el error más difícil de encontrar en c ++", pero todavía estoy interesado en lo que otras personas pueden pensar / pueden haber encontrado.

La idea para esta pregunta surgió durante una discusión con un amigo. Estuvimos de acuerdo en que debe ser bastante simple sabotear un proyecto de cpp al incluir de forma delicada los errores en el código fuente que usted envía ... Pero lo mejor que pudimos pensar fue utilizar variables sin inicializar (lo que lleva a fallas de segmentación aleatorias en tiempo de ejecución) . Estoy seguro de que hay mejores maneras ...?!

Características buscadas del código defectuoso:

  • Debe verse como un código válido a primera vista
  • no debe detener la compilación del código (demasiado obvio)
  • si es posible, el error debería parecer que podría haber sido un error (si se lo encontrara)
  • el error debe ser lo suficientemente grave como para impedir que el software se envíe (por ejemplo, fallas aleatorias, mal funcionamiento lógico del código, etc.)

Aún así, aunque debe ser notable, no debería ser obvio justo después de la presentación del código ... Bueno, entiendes la idea.

No se preocupe, nuestras consideraciones son puramente teóricas (no planeamos sabotear ningún proyecto). Simplemente consideramos que este es un experimento mental lo suficientemente bueno como para compartirlo con otros :-)

En breve:

¿Cuál es la forma más sutil de sabotear el código fuente que puede pasar desapercibida en un compromiso diferencial (como git) pero que en última instancia evitará una versión del software?


Diría que, por mucho, lo más frustrante para mí ha sido usar = lugar de == . Por ejemplo:

while(foo = bar) {}

en lugar de

while(foo == bar) {}

Esencialmente, cualquier cosa que haga que el código funcione incorrectamente en lugar de colapsar realmente me hace golpear mi cabeza contra una pared.

Menciones honoríficas:

  • Usando el operador matemático incorrecto - + / *
  • Similar a = vs == , error & para && o | para || .
  • Optimización prematura en algo como vector<bool> ( Lea aquí si todos son como "¿Qué?")
  • Tener dos o más clases con el mismo nombre y usar el incorrecto.

No es demasiado obvio:

if (foo =! foobar)

Y podemos agregar un truco para deshacernos de las advertencias del compilador:

if ( (i =! 3) && (j==1))


No es realmente un error, pero hago esto en algún lugar en un archivo de origen aleatorio cuando lo encuentro molesto cuando las versiones de lanzamiento son más lentas que las versiones de depuración. :)

#ifdef NDEBUG namespace { struct foo { foo() { sleep(rand() % 4); } } bar; } #endif


No he sido víctima de esto todavía, pero las conversiones implícitas pueden llevar a cosas malas. Mira esto:

class Foo { public: Foo(int a, OtherClass* b = NULL); };

¡Ahora (sin una palabra clave explícita) todos los métodos que esperan un Foo por valor / referencia de const también aceptarán un int!


Tal vez sea un robo descarado de esta pregunta , pero creo que encaja bastante bien en esta categoría.

Si tiene cadenas de bytes codificadas, todas de la misma longitud (por ejemplo, algo que podría usar con las redes), puede aprovechar la oportunidad para disimularlo:

const unsigned char someBytes[] = "text/0abc123";

Podría, con un pequeño interruptor, convertirse en:

const unsigned char someBytes[] = "text/0123abc";

La diferencia es que el primero tiene 12 caracteres, pero el segundo solo tiene 10 caracteres, debido al literal octal en el medio. Si surge la situación, esto indudablemente sería agravante de rastrear.


Una vez me retuvieron durante la mayor parte de un mes porque en las compilaciones de lanzamiento, la clasificación de nuestra CArray (Por Microsoft como parte de MFC) sería un error de segregación aleatoria, pero las compilaciones de depuración estaban bien. Lo reemplazamos con un std::vector y el problema se resolvió. No fue hasta meses después que alguien me informó que CArray no usa el operador de asignación de elementos y en su lugar usa memcpy ( source ). Esto claramente corrompe cualquier objeto contenido con un operador de asignación no trivial, pero es un contenedor estándar, por lo que todos asumen que es seguro. Entonces, si uno reemplaza std::vector con CArray en algunos lugares clave ...

Como nota, Microsoft dice que no use los contenedores MFC y que use los contenedores STL ahora.


struct { int foo char bar } while (foobar != 10); { //do something here }

1) Olvidarse de poner un; después de una estructura o poner una; después de un bucle WHILE

randn() //user created function rand() //library function

2) Nombrar una función que tenga un nombre similar a una función predefinida