Compiling C with optimization flag
I am comparing two assembly forms of two C files, one with an optimization flag (-O2), and the other without.
My question is:
Why is that in the optimized assembly version, the compiler puts the main function after all the helper functions, whereas the helper functions come first in the original assembly code. What does that mean in terms of efficiency? Can someone please elaborate?
Here is the original C file. Thanks!
// Based on a source file found in a beginner's discussion on multidimensional arrays here:
// http://www.dreamincode.net/forums/topic/71617-3d-arrays/
#include <stdio.h>
#include <string.h>
int validColor( char *str );
int mathProblem( char *str );
// 1) Asks from six 'theoretical' different users one of two questions,
// allowing only three answers for each.
// 2) Stores the response into a multidimensional array
int main( void )
{
char myArray[ 6 ][ 3 ][ 20 ]; /* Six users, three questions, and up to 19 characters per answer
(strings are '\0' terminated), though no "true" answer is that long */
int i, valid;
/* User instructions */
for( i = 0; i < 6; i++ )
{
if ( i % 2 == 0 )
{
valid = 0;
while( valid == 0 )
{
printf( "Enter your favorite color : " );
fgets( myArray[ i ][ 0 ], 20, stdin ); /* Get answer to first question */
if( myArray[ i ][ 0 ][ 0 ] == '\n' ) /* If the user just presses enter, move to next question */
break; /* Jump out of while loop */
valid = validColor( myArray [i ][ 0 ] ); /* Call function to validate answer */
}
}
if ( i % 2 == 1 )
{
valid = 0;
while( valid == 0)
{
printf( "The roots of (x - 4)^2 : " );
fgets(myArray[ i ][ 0 ], 20, stdin); /* Get answer to second question */
if(myArray[ i ][ 0 ][ 0 ] == '\n') /* If the user just presses enter, move to next question */
break; /* Jump out of while loop */
valid = mathProblem( myArray[ i ][ 0 ] ); /* Call function to validate answer */
}
}
}
return 0;
}
int validColor( char *str )
{
if( strcmp( str, "Black\n" ) == 0 )
return 1;
if( strcmp( str, "开发者_高级运维Red\n" ) == 0 )
return 1;
if( strcmp( str, "Blue\n" ) == 0 )
return 1;
return 0; /* If no match above, answer is not valid */
}
int mathProblem( char *str )
{
if ( atoi( str ) == 2 ) /* Function call for analysis purposes */
return 1;
if ( strcmp( str, "-2\n" ) == 0 )
return 1;
if ( strcmp( str, "+2\n" ) == 0 )
return 1;
return 0; /* If no match above, answer is not valid */
}
For the efficiency, John is completely right. After all is compiled in an object file, functions are just entries in a symbol table, order doesn't matter.
For your question why this order appears so:
- when not optimizing, all calls to functions are just references to the address of the function. The compiler can then easily emit the object code in the order it encounters the definitions of the functions.
- when optimizing, the compiler replaces (at least potentially) all calls to small functions for which it has the definitions at hand by inline code. So generally he can't emit the code when he encounters the function but has to wait until he eventually sees the declaration of all called functions. The emission order is thus something like an invers linear ordering of the call graph.
It will make no real difference in terms of efficiency.
精彩评论