¿El comstackdor optimizará los argumentos no utilizados de la función estática?

Tengo un grupo de funciones que están declaradas como static y fastcall . La mayoría de ellos hace uso de un puntero a una estructura que sirve más o menos el papel de this en C ++. Algunas de las funciones no necesitan nada en la estructura, pero por uniformidad quiero pasarles el puntero de todos modos. ¿Notará el comstackdor que el argumento no se usa y omite asignarle un registro?

Escribí este progtwig sin sentido para probar esto. Tiene algún código sin sentido en la función, y lo llama varias veces porque, de lo contrario, el comstackdor simplemente incorporó toda la llamada a la función haciendo que la prueba fuera inútil. (Es una mezcla extraña de C y C ++, lo sé … código estúpido, pero todavía funciona para demostrar el problema)

 #include  #include  #include  using namespace std; struct demo { int a; char ch; }; static void __fastcall func(struct demo* d) { for(int i = 0; i < 100; i++) { std::vector a; std::sort(begin(a), end(a)); printf("THis is a test"); printf("Hello world\n"); } } int main() { // void*p = (void*)&func; struct demo d; func(&d); func(&d); func(&d); func(&d); func(&d); func(&d); func(&d); //printf((const char*)p); } 

Como está escrito allí, la función llama a comstackr esto:

  func(&d); 00F61096 call func (0F61000h) func(&d); 00F6109B call func (0F61000h) func(&d); 00F610A0 call func (0F61000h) func(&d); 00F610A5 call func (0F61000h) func(&d); 00F610AA call func (0F61000h) func(&d); 00F610AF call func (0F61000h) func(&d); 00F610B4 call func (0F61000h) 

Lo que muestra que el comstackdor de hecho omitirá el parámetro si no se usa. Sin embargo, si descomento las dos líneas allí para tomar la dirección de la función, entonces las cosas cambian, en su lugar generó esto:

 00C71099 lea ecx,[esp] 00C7109C call func (0C71000h) func(&d); 00C710A1 lea ecx,[esp] 00C710A4 call func (0C71000h) func(&d); 00C710A9 lea ecx,[esp] 00C710AC call func (0C71000h) func(&d); 00C710B1 lea ecx,[esp] 00C710B4 call func (0C71000h) 

Donde se envía el puntero.

Supongo que, en el primer caso, el comstackdor puede demostrar que si generó una convención de llamada personalizada a la función de que no puede haber ningún efecto visible para el usuario, pero en el segundo caso en el que lleva un puntero a la función, la función podría llamarse desde otro módulo comstackdo por separado que no tiene forma de saber si el parámetro es necesario o no. Aunque en este caso no importaría si el registro se configuró o no, en general, el comstackdor debe ajustarse al patrón de llamada exacto, por lo que supongo que generó el código más general y no utilizará convenciones de llamada personalizadas si puede No pruebe que puede ver todo el código que podría llamar a la función.

De todos modos, para responder a la pregunta, no, el comstackdor no siempre pasará los parámetros no utilizados en un registro, pero ciertamente no escribiría ningún código que dependa de ningún comportamiento específico aquí como cambio de código no relacionado en otro lugar (tomando la dirección de la función), cambiado Ese comportamiento y no hay nada garantizado por cualquier estándar que pueda ver.

En primer lugar, el comstackdor debería advertirle acerca de los argumentos de función no utilizados, si usa los indicadores de comstackción adecuados (-Wall, por ejemplo). Recomendaría dejar los argumentos que no usa fuera de la lista de argumentos, aunque yo Supongo que se optimizarían lejos. Sin embargo, lo que podría hacer para asegurarse es comstackr su código dos veces, una vez con los argumentos y una vez sin, y hacer una diff entre los binarios y ver si coinciden. Creo que debería depender del comstackdor que uses y de los indicadores de optimización.

Aclamaciones,

Andy

Puede omitir el argumento en la definición de la función. Esto le dará la pista al comstackdor de que no se usa un argumento específico, se beneficiará de él y optimizará el código

función nula (estructura demo *) {…}