Распространенные ошибки - C (СИ) - Ответ 10047931

Продолжая данную проблему.

Квалификатор const в С и С++ работает по разному. В последнем, он при возможности создаёт константу времени компиляции. Но в С этого не происходит. Чем это грозит?

Когда используется запись вида

const int N = 30;

в С++ создаётся константа времени компиляции, в С лишь переменная с запретом на изменение значения (read-only). И дальнейшее объявление вида

int arr[N];

для С внезапно даст VLA (variable-length array) массив. Но это лишь при условии, что стандарт поддерживает данную опцию (C89 не поддерживает, С99 поддерживает, С11 optional). Также, VLA есть в gnu расширении. Плохо это по двум причинам:

1. Для VLA массивов память выделяется через alloca, то есть из стека системы, а это

лучше не делать

, учитывая, что размер массива может быть и достаточно большим, а проверить выделилась ли память с помощью alloca нельзя (в отличие от malloc). Примечание: реализация VLA может отличаться, стандарт не накладывает ограничений на этот счёт. Однако, GCC использует именно описанный способ.

2. Сам того не подозревая, автор вносит зависимость на стандарт/расширение. А учитывая, что VS до сих пор не научилась работать с VLA, при переносе кода и честной компиляции сишным компилятором, могут вывалиться ошибки.

Решение:

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

Для задания констант (в данном случае, идентификаторов), известных во время компиляции и позволяющих задать статический массив определённого размера, в С используют препроцессорную директиву define. Подробнее о её работе вы можете ознакомиться

тут

.

В данном случае, стоило бы написать

#define N 30

Вернуться к обсуждению:

Распространенные ошибки C