Модификатор const в Си - PullRequest
       1

Модификатор const в Си

5 голосов
/ 31 марта 2011

Я часто путаюсь, когда возвращаюсь в C из-за невозможности создать массив, используя следующий шаблон инициализации ...

const int SOME_ARRAY_SIZE = 6;
const int myArray[SOME_ARRAY_SIZE];

Мое понимание проблемы состоит в том, что оператор const негарантируют постоянство, а лишь утверждают, что значение, на которое указывает SOME_ARRAY_SIZE, не изменится во время выполнения.Но почему компилятор не может предположить, что значение является постоянным во время компиляции?Там написано 6 прямо в исходном коде ...

Я думаю, что мне не хватает чего-то основного в моем фундаментальном понимании C. Кто-то поможет мне здесь.:)

[ОБНОВЛЕНИЕ] Прочитав немного больше о C99 и массивах переменной длины, я думаю, что понимаю это немного лучше.Я пытался создать массив переменной длины - const создает не константу времени компиляции, а константу времени выполнения.Поэтому я инициализировал массив переменной длины, который действителен только в C99 в области функций / блоков.Массив переменной длины в области видимости файла невозможен, так как компилятор не может назначить фиксированный адрес памяти неограниченному массиву. [/ UPDATE]

Ответы [ 5 ]

6 голосов
/ 31 марта 2011

Ну, в C ++ семантика немного другая.В C ++ ваш код будет работать нормально.Вы должны различать 2 вещи, const и constant expression.Как вы уже сказали, Const означает, что значение доступно только для чтения.константное выражение, с другой стороны, означает, что значение является известным временем компиляции и является константой времени компиляции.Семантика const в C всегда первого типа.Единственными константными выражениями в C являются литералы, поэтому #define используется для такого рода вещей.

Однако в C ++ любой объект const, инициализированный с помощью константного выражения, сам по себе является константным выражением.

Я не знаю точно, ПОЧЕМУ это так в C, просто так оно и есть

4 голосов
/ 31 марта 2011

Проблема в том, что синтаксис языка требует целочисленного значения между [].SOME_ARRAY_SIZE по-прежнему является переменной (даже если вы сказали компилятору, что никто не может изменять его!)

2 голосов
/ 31 марта 2011

Ключевое слово const в основном предназначено только для чтения. На самом деле это не означает, что базовое значение не изменится, даже если это так в вашем примере.

Когда дело доходит до указателей, это более ясно:

void foo(int const * p)
{
  if (*p == 100)
  {
    bar();
    /* Here, the compiler can not assume that *p is 100 */
  }
}

В этом случае компилятор не должен принимать код в вашем примере, поскольку он требует, чтобы размер массива был постоянным. Если он примет это, пользователь может позже столкнуться с проблемами при переносе кода на более строгий компилятор.

1 голос
/ 31 марта 2011

Вы можете сделать это в C99, и некоторые компиляторы до C99 также поддерживали это как расширение C89 (например, gcc).Если вы застряли со старым компилятором, который не поддерживает C99 (например, MSVC), то вам придется сделать это old skool и использовать #define для размера массива.

Обратите внимание, что вышеприведенные комментарии применяются только к таким объявлениям в локальной области (т. Е. Автоматическим переменным).C99 все еще не допускает такие объявления в глобальном масштабе.

0 голосов
/ 31 марта 2011

Я только что провел очень быстрый тест с моим файлом Xcode и Objective C, который у меня в данный момент был открыт на моей машине, и поместил его в файл .m:

const int arrs = 6;
const int arr[arrs];

Это компилируется без проблем.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...