Статическое выделение С++ против динамического распределения

Я знаю разницу между статическим (определяемым компилятором) и динамическим (определяемым во время выполнения) распределением. Чего я не понимаю, так это того, что происходит в случае, когда у нас есть следующий код, который успешно выполняется: при компиляции мы не знаем значение nbr, но у нас есть статическое распределение с int tab[nbr]!

#include <iostream>

using namespace std;

int main()
{
    int nbr;
    cout << "Enter nbr of student in class = ";
    cin >> nbr ;

    int tab[nbr];
    for (int i=0; i < nbr ; i++) {
        tab[i] = i;
    }

    for (int i=0; i < nbr ; i++) {
        cout << tab[i] << endl;
    }

    return 0;
}

person M Ko    schedule 15.08.2020    source источник
comment
int tab[nbr]; не является допустимым C++ (использует расширение VLA).   -  person Jarod42    schedule 15.08.2020
comment
int tab[nbr]; будет распределением во время выполнения, но с автоматическим хранением (в основном стеком).   -  person Jarod42    schedule 15.08.2020
comment
Да, int tab[nbr] недействителен, но некоторые компиляторы все еще разрешают его (по крайней мере, с настройками по умолчанию) для удобства.   -  person HolyBlackCat    schedule 15.08.2020


Ответы (2)


Фрагмент, который вы показываете, не соответствует ни одному стандарту C++. Однако некоторые компиляторы C++, такие как GCC, реализуют массивы переменной длины, изначально особенность C99. Выделяются ли они в стеке или в куче, зависит от компилятора (т.е. детали реализации).

РЕДАКТИРОВАТЬ: вы упоминаете в комментарии, что ваш компилятор не выдает предупреждений даже с флагом -pedantic. Какой компилятор вы используете? GCC 10.1.0 действительно предупреждает: warning: ISO C++ forbids variable length array ‘tab’ в моей системе.

person Peter    schedule 15.08.2020

Ну, in C, или в большинстве компиляторов, которые интегрируют язык, он работает именно так (с небольшой разницей в реализации языка между компиляторами с, потому что стандартные с запаса для этого, так что никогда не знаешь, что является частью стандарта и что он делает часть конкретной реализации c в конкретном компиляторе, не видя документации по стандарту): когда компилятор знает, что такое значение, то есть когда вы определяете переменную без какой-либо базы на каком-либо другом значении в решении структура, которая зависит от динамического значения, в результате она будет известна компилятору, однако, если верно обратное, истина будет dynamic allocation, что соответствует вашему случаю. Проще говоря, если вы знаете значение переменной, оно определяется во время компиляции, в противном случае это время выполнения, что соответствует случаю tab[nbr], который зависит от dynamic value.

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

Но без всякого контекста конкретных языков программирования скомпилированные переменные — это просто значения, которые заменяются их значениями, определенными в момент компиляции, и без какого-либо вмешательства в момент выполнения, тем временем переменные во время выполнения загружаются в оперативную память , и администрируется там, и процессором. sПричина, по которой они зависят от циклов ЦП (которые сильно различаются, можно проверить на вкладке системы Windows, измеряются в Heartz): перемещается, удаляется и создается, это зависит от производительности, это плохо для ЦП и для вас .

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

различия:

  • Динамические переменные управляются процессором, который в оперативной памяти использует для вычислений, зависящих от непредсказуемых значений, таких как задержка выделения пространства или размер пользовательского ввода.

  • Переменные во время компиляции управляются компилятором с целью повышения производительности, чтобы процессор не тратил время на вычисления, результат которых каким-то образом предсказуем во время компиляции.

Использованная литература:

person Loliconaoquadrado    schedule 15.08.2020
comment
Спасибо всем за ваши ответы. Итак, если предположить, что int tab[nbr]; не является допустимым стандартом С++ и использует расширение, я пытаюсь отключить расширения в clode::block, но код по-прежнему выполняется успешно. - person M Ko; 15.08.2020
comment
Под отключением расширения я имел в виду проверку предупреждений -pedantic. Обратите внимание, что у меня также нет предупреждений. Код выполняется без ошибок и предупреждений. - person M Ko; 15.08.2020