Errores, fallos, preguntas - página 2725

 
Vict:

¿Cree que su Sharp apareció en un campo limpio? Con raíces en C, la estructura es un contenedor mudo sin azúcar adicional.

Bueno, el hombre evolucionó a partir de un mono. Pero eso no significa que el hombre sea un mono tonto "sin más azúcar", ¿verdad? ) Ya he explicado que en realidad las estructuras de MQL = estructuras de C#, con una pequeña diferencia: en C# pueden seguir implementando interfaces. ¡Interfaces, Carl! )

¿Cómo puedes estar tan seguro? Llamar a una función desde otra unidad de traducción/otro módulo/ciclos/compilador fuera de tono/... . No sobreestime las capacidades del optimizador. No se trata de una optimización de elisión de copias que los compiladores están obligados a hacer. Si los optimizadores se vuelven tan listos y deja de costar nada, escribirán en el próximo estándar de C: "la inicialización por defecto no deja un objeto en estado indefinido".

Porque es la cosa más trivial y primitiva que ni siquiera se puede llamar optimización. Creo que todos los compiladores lo hacen por defecto, incluso en el modo de depuración. ¿Qué puede ser más fácil? Durante el análisis del código, tienes que seguir el acceso a las variables. Si hay una operación de escritura repetida y no hubo ninguna operación de lectura, entonces corta la entrada anterior.

Puedes ignorarlo, pero entonces no te sorprendas de que los codificadores decentes te miren como un codificador de mierda cuando vean tus estructuras rellenas de funciones

Yo más bien llamaría a tu enfoque de la operación no inicializada código de mierda. ¿Cuál es la principal cualidad que debe poseer un programa de ordenador? Estabilidad. Con los mismos datos de entrada debe dar resultados inalterables. Y tú propones olvidarte de ello. En algún lugar te olvidaste de inicializar una variable, en algún lugar añadiste un nuevo campo a la estructura que quedó sin inicializar en todo el programa, y el programa siguió adelante. El programa funciona así y así...

El lenguaje C se creó en un pasado lejano, cuando las capacidades del hardware eran muy pobres, por lo que gran parte del trabajo de optimización se dejaba en manos del programador. Si te pica tanto, ¿por qué te refieres a C y no a Assembler, por ejemplo? Codifica los sistemas de comercio en Assembler. Seguro que serán los más rápidos, incluso puede que se adelanten al mercado )

 
Alexey Navoykov:

Porque es la cosa más trivial y primitiva, que apenas puede llamarse optimización. Creo que todos los compiladores lo hacen por defecto incluso en modo Debug. ¿Qué podría ser más fácil? Mientras se analiza el código, controlar el acceso a las variables. Si hay una operación de escritura repetida y no hubo ninguna operación de lectura, entonces corta la entrada anterior.

Si el programa fuera completamente predecible en tiempo de compilación, no tendría que ejecutarse en tiempo de ejecución en absoluto. Por definición, debe tomar algo del mundo exterior y emitir un resultado basado en él, y esa es la incertidumbre que se interpone en el camino del optimizador. Otro secreto: las bibliotecas compartidas se enlazan con la aplicación en tiempo de ejecución, el optimizador no puede rastrear nada allí. Hay un millón de casos más que deben ser desechados. (¡Un millón, Karl!)

En algún lugar me olvidé de inicializar una variable o añadí un nuevo campo a una estructura que quedó sin inicializar en todo el programa, y el programa sigue. El programa funciona así y así...

En algún lugar he multiplicado por 2 en lugar de por 3, he llamado a fn() en lugar de a fn_(), ... . Si tus manos están mal, estás en problemas.

El lenguaje C se creó hace mucho tiempo, cuando las capacidades del hardware eran muy pobres, por eso gran parte del trabajo de optimización se dejó en manos del programador. Si te mueres de ganas de hacerlo, ¿por qué te refieres a C y no a Assembler? Codifica los sistemas de comercio en Assembler. Seguro que serán los más rápidos, quizás incluso por delante del mercado.

para su referencia: las normas C (las últimas, no son normas C++): C11, C18, C2x se está preparando. Más bien, escribió esto como resultado de la incompetencia.
 
Vict:

Si el programa fuera completamente predecible en tiempo de compilación, no sería necesario ejecutarlo en tiempo de ejecución. Por definición, debe tomar algo del mundo exterior y obtener un resultado basado en él, y esto es una incertidumbre que dificulta al optimizador. Otro secreto: las bibliotecas compartidas se enlazan con la aplicación en tiempo de ejecución, el optimizador no puede rastrear nada allí. Hay un millón de casos más que deben ser desechados. Un millón, Karl)

Elintercambio de datos con el mundo exterior son casos especiales y requieren soluciones especiales. Estamos hablando de la programación como tal y de aquellos casos en los que el compilador está garantizado para saber que la variable no es controlada desde el exterior. Y esto debe ser la gran mayoría de los casos. De lo contrario, usted tiene una programación puramente sistema, que es realmente mejor hacer en C, o incluso mejor - en ensamblador.

En algún lugar multiplicado por 2 en lugar de 3, llamado fn() en lugar de fn_(), . . Si tienes las manos torcidas, problemas.

Si multiplicas por 2 en lugar de por 3, obtienes un error estable en el programa que es fácil de diagnosticar y encontrar. Y si la variable no está inicializada obtienes algo que ahora funciona y luego no, de vez en cuando, con consecuencias imprevisibles. En general, es bastante extraño que te explique cosas tan básicas, haciéndome pasar por un programador experimentado.

 
Alexey Navoykov:

El intercambio de datos con el mundo exterior - estos son casos especiales, y requieren soluciones especiales. Pero estamos hablando de la programación como tal, y los casos en que el compilador está garantizado para saber que la variable no se controla desde el exterior. Y esto debería ser la gran mayoría de los casos. De lo contrario, se obtiene una programación puramente sistema, que es realmente mejor hacer en C, o incluso mejor - en ensamblador.

La comunicación con el mundo exterior es una parte esencial de cualquier programa. Permítanme repetirlo: si no, se puede averiguar en tiempo de compilación. Por ejemplo, ¿el compilador cortará la inicialización aquí?

int i = 54;
if (read_socket() == SIGNAL) {
   fn(i);
}
i = 100;
...

// естественно, что никто не пишет такой бред:
int q = 3;
q = 7;
q = 9;
fq(q);

Obviamente, no tiene idea de lo que read_socket() devolverá. Todo el programa está "impregnado" de interacción con el mundo exterior. + añadir una llamada a módulos externos aquí... .

Si lo multiplicas por 2 en lugar de por 3, obtienes un error estable en el programa que es fácil de diagnosticar y encontrar. Y con una variable no inicializada obtienes algo que ahora funciona y luego no, de vez en cuando, con consecuencias impredecibles. La verdad es que es bastante extraño que te explique cosas tan básicas a ti que te haces pasar por un programador experimentado.

Mira, si quieres conseguir un error estable, es muy sencillo inicializar la pila:

int main() {
    if (true)
        int init_stack[10000] {0};
}

La inicialización de la memoria desde HIP también es un juego de niños. Si nos encontramos con alguna trampa de representación, obtendremos un volcado del núcleo en absoluto.

Una vez más, si los optimizadores fueran muy inteligentes, equipararían el init por defecto con el init de valor con la inserción de instrucciones de inicialización por parte del compilador como es necesario todavía en algunos C11, pero por desgracia. Nadie obliga, si no se quiere, a hacer T val{}; Cansado de explicar cosas elementales.

 
Vict:

Una vez más, si los optimizadores fueran muy inteligentes, equipararían el init por defecto con el init de valor con el compilador insertando instrucciones de inicialización según sea necesario en algunos C11, pero por desgracia. Nadie obliga, si no lo quieres, haz T val{}; Cansado de explicar cosas elementales.

Porque, según tengo entendido, el estándar C++ describe las reglas de manera muy formal, sin contextualización. Es decir, la inicialización siempre o nunca. A modo de comparación, en C# puedes declarar una variable sin inicialización, pero más adelante en el código debe ser necesariamente inicializada. Es decir, el compilador analiza el código que sigue y no sólo el comando actual. Esto está previsto en las reglas del lenguaje, pero la norma no prevé ningún análisis en C++. Así que si fuerzan la inicialización, te quejarás de que quiero controlar e inicializar todo yo mismo. )

 
Alexey Navoykov:

Porque el estándar C++, según tengo entendido, describe las reglas muy formalmente, sin contextualización. Es decir, la inicialización es siempre o nunca. En comparación, en C# puedes declarar una variable sin inicialización, pero más adelante en el código debe ser necesariamente inicializada. Es decir, el compilador analiza el código que sigue y no sólo el comando actual. Esto está previsto en las reglas del lenguaje, pero la norma no prevé ningún análisis en C++. Así que si fuerzan la inicialización, te quejarás de que quiero controlar e inicializar todo yo mismo. )

Lo que ocurre es que las soluciones probadas llegan hasta allí y, si funcionan a la primera, provocando a menudo una sobrecarga innecesaria, nadie las incluye. Por ejemplo, han prescrito en el estándar un MUST para que el compilador haga copy elision en c++17.

 

El tema se llama "Bugs, bugs, questions".

Por favor, crea un tema donde se discuta sobre MQL vs C#,C++, y otras cosas relacionadas con la sintaxis, compiladores y entrenamientos mentales.

Estás ensuciando el hilo y otras preguntas y mensajes de usuarios se ahogan en tu discusión.

Me preguntan dónde hacer una pregunta - me dirigen aquí y la respuesta es: "Los tíos están discutiendo durante cien páginas allí, así que no voy a interferir, el resto no tiene sentido ...

 
const int DEFAULT_INT_VALUE   = 147;
input int thisIsAnInput       = DEFAULT_INT_VALUE;
'NoConstForInput.mq5' NoConstForInput.mq5 1 1
'DEFAULT_INT_VALUE' - constante esperada NoConstForInput.mq5 13 33
1 errores, 0 avisos 2 1

Construir 2361 y 2390

 
Alain Verleyen:
'NoConstForInput.mq5' NoConstForInput.mq5 1 1
'DEFAULT_INT_VALUE' - constante esperada NoConstForInput.mq5 13 33
1 errores, 0 avisos 2 1

Construir 2361 y 2390

#define  DEFAULT_INT_VALUE 147
 
Vict:

Mira, si quieres conseguir un error estable, inicializar la pila es muy fácil:

La inicialización de la memoria desde un HIP también es un juego de niños. Si nos encontramos con alguna trampa de representación, obtendremos un volcado del núcleo por completo.

Un último comentario, por favor no te enfades con los moderadores )).

Necesito aclarar por qué la pila tiene valores diferentes de una llamada a otra. Se trata de proteger https://ru.wikipedia.org/wiki/ASLR, y ni siquiera es necesario inanalizar nada en absoluto, como he dicho antes. En mi caso - ejecuto el software bajo gdb (depurador), que lo situará en la misma dirección cada vez que se ejecute, es decir, la pila no se contaminará con direcciones de retorno "aleatorias".