Области видимости (Scoping)

Область видимости переменной определяется тем, где она объявлена. Если она объявлена вне всех функций, то имеет глобальную область видимости, начинающуюся с места объявления и до конца текущего шейдера. Соответственно если объявлена внутри while или for, то область действие до следующей итерации. (Смотри раздел 6.2 “Selection” и раздел 6.3 “Iteration”) В противном случае если он объявлен как оператор внутри составного оператора, то область видимости будет до конца этого оператора. Объявления параметров функций и тело вместе формируют единое область видимости, вложенную в глобальную область видимости. Внутри if нельзя объявлять переменные, потому не формирует новую область видимости.

Область видимости начинает свое действие сразу после инициализатора, если он присутствует,  или сразу после объявления имени, если нет. Несколько примеров:

int x = 1;
{
    int x = 2, y = x; // y проинициализирован значением 2
}
struct S
{
    int x;
};
{
    S S = S(0); // 'S' используется только как 
                //  структура и конструктор
    S;          // 'S' теперь используется как переменная
}
    int x = x; // Ошибка если х ранее не был определен.
               // Если предыдущее определение х было в этой
               // области видимости, это приведет к
               // ошибке повторного определения.
int f( /* вложенная области видимости начинается здесь */ int k)
{
    int k = k + 3; // ошибка повторного определения имени k
    ...
}
int f(int k)
{
    {
        int k = k + 3; // второй k это параметр, 
                       // инициализируемый вложенным первым k
        int m = k      // использование нового k,  
                       // который скрывает параметр
    }
}

Для циклов for  и while подпроходы как таковые не вводит новую область имен переменных, поэтому следующее повторное определение приведет к ошибке времени компиляции:

for ( /* вложенная область видимости начинается здесь */ int i = 0; i < 10; i++) {
 int i; // ошибка повторного определения
}

Тело цикла do-while добавляет новую область видимости, действующую только между do и while (не включая условие проверки while), вне зависимости от того, является тело простым или сложным:

int i = 17;
do
 int i = 4; // вложенная область видимости
while (i == 0); // i равно 17, за пределами тела do-while

Оператор следующий за switch (…) формирует вложенную области видимости.

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

Встроенные функции определены за пределами области видимости, в которой пользователи определяют глобальные переменные. То есть глобальная область видимости, доступна для определяемых пользователем функций и глобальных переменных, вложена в область, содержащей встроенные функции. Когда имя функции переопределяется во вложенной области видимости, функция со схожим именем из внешней областей становится скрытой. Объявление функции (прототипирование) не может встречаться внутри функции; они должны быть в глобальной области видимости или, для встроенных функций, за пределами глобальной области видимости, в противном случае возникает ошибка времени компиляции.

Общие глобалы — это глобальные переменные, объявленные в отдельно скомпилированных единицах (шейдерах) на одном языке (т.е. одном этапе, например вершинном) и связанные друг с другом на этапе создания программы. (Глобалы формирующие связи между двумя разными шейдерными языками описываются в других разделах) Общие глобалы имеют одно пространство имен и должны быть иметь одинаковый тип. Они будут храниться в одной области памяти.

Общие глобальные массивы должны иметь одинаковый базовый тип и одинаковый явный размер. Массив с неявным размером в одном шейдере может быть задан с явным размером в другом шейдере того же этапа. Если ни один шейдер на этапе не имеет явного размера, размер задается наибольшим (на 1 больше, чем самый большой используемый индекс) неявным размером на данном этапе. Не существует установки размера между этапами. Если нет статического доступа к массиву неявного размера на этапе, объявляющем его, тогда массив получает размер 1, что уместно. когда массив определен внутри интерфейсного блока, который доступен другим этапам или приложениям (другие неиспользуемые массивы могут быть устранены  оптимизатором).

Общие глобальные скаляры должны иметь полностью идентичные имена типов и определения типов. Структуры должны иметь идентичное имя, последовательность имен типов и определения типов, а имена членов одинаковый тип. Это правило применяется рекурсивно для всех вложений или вложенных типов. Если общий глобал имеет несколько инициализаторов, инициализаторы должны быть константными выражениями, и все они должны иметь одинаковое значение, в противном случае возникнет ошибка времени линковки. (Если общий глобал имеет только один инициализатор, то он может не быть константным выражением).

Main Admin

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *