Потеряна ли эффективность при объявлении автоматической переменной в часто открываемой области блока {}? - PullRequest
2 голосов
/ 10 июня 2019

В K & R указано:

Автоматическая переменная, объявленная и инициализированная в блоке, инициализируется каждый раз при вводе блока.

Вот фрагмент кодаисключительно для сообщения вопроса.Показаны два варианта;объявляя error_string в теле основной функции и объявляя его в области видимости блока if ().

Вопрос в том, можно ли использовать компилятор для оптимизации действия многократного создания экземпляра, если используется объявление option2строка?

Это может сделать код более читабельным для объявления переменных, наиболее близких к тому, где они используются.Максимальное ограничение их области применения является, пожалуй, хорошей практикой проектирования.Может ли это иметь какой-либо заметный ущерб эффективности?

#define MAX_ERROR_STRING_LEN 1024

void process_results(int *results, int n_results)
{
    int i;
    char error_string[MAX_ERROR_STRING_LEN]; //option1

    for (i = 0; i < n_results; i++) //suppose n_results == 1 million, 98% "FAILURE"
    {
        if (results[i] == FAILURE)
        {
            char error_string[MAX_ERROR_STRING_LEN];//option2

            get_error_string(error_string, MAX_ERROR_STRING_LEN - 1);

            fprintf(debug_log, "Error: %s\n", error_string);
        }
    }
}

на соответствующей ноте, следует ли этого избегать:

    for (i = 0; i < strlen(error_string); i++)
        printf("%c", error_string[i]);

в пользу:

    int len = strlen(error_string);
    for (i = 0; i < len; i++)
        printf("%c", error_string[i]);

или это будет оптимизировано, несмотря на зависимость от данных времени выполнения?

Редактировать - без изменений, просто добавив исследование:

I думаю это подтверждает, что переменные области видимости блока неоднократносоздано и уничтожено (для программиста):

A.4.1 Класс хранения Существует два класса хранения: автоматический и статический.Несколько ключевых слов вместе с контекстом объявления объекта определяют его класс хранения. Автоматические объекты являются локальными для блока (Par.9.3) и отбрасываются при выходе из блока.

Большая часть остальных относится к лексической области, а не к связи:

A.11.1 Лексическая область действия ... Область действия параметра определения функции начинается в начале блока, определяющего функцию, и сохраняется в функции;область действия параметра в объявлении функции заканчивается в конце объявления.Область действия идентификатора, объявленного в начале блока, начинается в конце его объявления и сохраняется до конца блока.

Относительно лексической области действия?:

Область имени - это часть программы, в которой можно использовать имя.Для автоматической переменной, объявленной в начале функции, область действия - это функция, в которой объявлено имя.Локальные переменные с одинаковыми именами в разных функциях не связаны.То же самое относится и к параметрам функции, которые в действительности являются локальными переменными.

также

Имя также имеет область действия, которая является областьюПрограмма, в которой она известна, и связь, которая определяет, относится ли то же имя в другой области к тому же объекту или функции.Область применения и связь обсуждаются в Пар. А.11.

1 Ответ

4 голосов
/ 10 июня 2019

Локальная переменная error_string не инициализирована, при объявлении ее с областью видимости блока вместо области функции нет никаких накладных расходов. Некоторые компиляторы могут выделять временное пространство стека для error_string при входе в область действия блока и освобождать его при выходе из этой области, что включает в себя одну инструкцию в обоих случаях, но большинство компиляторов выделяют пространство для всех локальных переменных за один шаг в начале функции.

Поскольку вы обеспокоены эффективностью, обратите внимание, что оба фрагмента кода, размещенные для печати строки, очень неэффективны по сравнению с этим:

    fputs(error_string, stdout);
...