Оценка компилятором размера объявления массива. Когда это происходит? - PullRequest
0 голосов
/ 17 февраля 2020

Это больше для ясности или лучшего понимания внутренней работы компиляторов: я начинаю изучать конструкцию компилятора и теорию компилятора.

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

То, что я хотел бы знать, это; когда происходит эта оценка? Это происходит во время прекомпиляции, токенизатора, синтаксического анализа и т. Д. c.? Кроме того, зависит ли это от конкретного компилятора, который используется? Наконец, определен ли момент времени этой оценки на каком-либо конкретном этапе компилятора в рамках языковых стандартов?

Фрагмент псевдокода. C или C ++

int main() {
    int x[5]; // When does the evaluation of the 5 for the array's size take place 
              // during the compilation process? 
              // Does it take place during pre-compiler or normal compilation time. 
    return 0;
}

Ответы [ 2 ]

3 голосов
/ 18 февраля 2020

Стандарт C определяет восемь этапов перевода:

  1. Физические исходные многобайтовые символы и последовательности триграфа сопоставляются с символами исходного набора символов.

  2. Каждый backsla sh, за которым следует новая строка, удаляется (объединяя две строки).

  3. Исходные символы сгруппированы в токены предварительной обработки, и каждая последовательность символы пробела заменяются одним пробелом, за исключением того, что сохраняются новые строки.

  4. Выполняются директивы предварительной обработки и операторы _Pragma, а вызовы макросов расширяются.

  5. Исходные символы в строках и символьные константы преобразуются в набор символов выполнения.

  6. Объединенные строковые литералы объединяются.

  7. Каждый токен предварительной обработки преобразуется в токен грамматики, а пробелы, разделенные пробелами, отбрасываются. Полученные токены анализируются и транслируются (компилируются).

  8. Все внешние ссылки разрешены (программа связана).

Разрешение константы Размеры массива, таким образом, происходят в фазе 7. Тем не менее, фазы в основном являются концептуальными. Этапы объясняют, как понимается язык C, а не то, как должен выполняться компилятор.

Для компиляторов, которые создают объектные модули, размеры массивов с длительностью хранения stati c обязательно разрешаются до того, как информация объекта написано, так как размер массива влияет на компоновку данных, которая должна быть полностью описана в объектном модуле. Обработка размеров массивов с автоматическим c сроком хранения теоретически может быть оставлена ​​до тех пор, пока программа фактически не выполнит код, который нуждается в них, поскольку это обязательно относится к массивам переменной длины. Однако это было бы расточительно, так как постоянные размеры массива легко обрабатываются во время компиляции, и предпочтительно, чтобы необходимые значения (например, объем стекового пространства, резервируемого при входе в функцию), скорее рассчитывались во время компиляции чем во время исполнения. Таким образом, можно ожидать, что обычные компиляторы разрешают все постоянные размеры массива во время компиляции (то есть до завершения объектного модуля для модуля перевода) и концептуально после этапа 6.

Дополнительная идентификация точек в процессе перевода, где массив Разрешенные размеры зависят от внутренних деталей реализации компилятора (или реализации C в целом).

1 голос
/ 17 февраля 2020

После прочтения комментариев от различных пользователей я пришел к выводу, что в стандарте нет ничего конкретного c. Существуют различия между C и C ++ в деталях их реализации того, разрешены ли массивы переменного размера в языке внутри фрейма стека.

Когда дело касается дизайна компилятора, для препроцессора нет контекста. Когда дело доходит до этапов компилятора, это зависит от языка, к которому он принадлежит, и кажется, что он также находится между c между компиляторами и их дизайном. Похоже, что это оставлено на усмотрение реализации компилятора, для которого выполняется эта оценка.

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

Спасибо всем за ваш вклад и отзывы. Пожалуйста, непременно исправьте меня, если я ошибаюсь, оставив комментарий под этим ответом.

...