Здесь действительно два вопроса:
- Оптимизирует ли компилятор выражения, найденные внутри макросов?
- Оптимизирует ли компилятор
sqrt()
?
(1) легко: да, это так.Препроцессор отделен от компилятора C и делает свое дело еще до запуска компилятора C.Так что если у вас есть
#define ROWS 15
#define COLS 16
#define NODES (ROWS*COLS)
void foo( )
{
int data[ROWS][COLS];
printf( "I have %d pieces of data\n", NODES );
for ( int *i = data; i < data + NODES ; ++i )
{
printf("%d ", *i);
}
}
Компилятор на самом деле увидит:
void foo( )
{
int data[15][16];
printf( "I have %d pieces of data\n", (15*16) );
for ( int *i = data; i < data + (15*16) ; ++i )
{
printf("%d ", *i);
}
}
И это зависит от обычной оптимизации констант во время компиляции.
sqrt()
хитрее, потому что он варьируется от компилятора к компилятору.В большинстве современных компиляторов sqrt () на самом деле является встроенным компилятором , а не библиотечной функцией - это выглядит как вызов функции, но на самом деле это особый случай внутри компилятора, который имеет дополнительную эвристику, основанную на математических законахаппаратные операции и т. д. В интеллектуальных компиляторах, где sqrt()
является таким частным случаем, sqrt()
постоянного значения будет внутренне преобразовано в постоянное число.В дурацких компиляторах это будет приводить к вызову функции каждый раз.Единственный способ узнать, что вы получаете, - это скомпилировать код и посмотреть на выпущенную сборку.
Из того, что я видел, MSVC, современные GCC, Intel, IBM и SN считают sqrt
внутренним.Старый GCC и некоторые дрянные поставляемые вендором компиляторы для встроенных чипов этого не делают.