6

Недавно я нашел интересное поведение г ++ по сравнению с MSVC++ 2008. Рассмотрим эту крошечную программу:разное поведение компиляторов с выделением массива

#include <cstdlib> 

const int ARR_LENGTH = 512; 

void doSomething(int iLen); 

int main(int argc, char** argv) 
{ 
    doSomething(ARR_LENGTH); 
    return 0; 
} 

void doSomething(int iLen) 
{ 
    int iTest[iLen]; 
    return; 
} 

Будет ли компилировать? Как вы думаете? Согласно моим знаниям о C (или C++, если на то пошло), это НЕ должно компилироваться, так как я могу вызвать функцию doSomething() с любым целым числом, которое я хочу, поэтому размер массива iTest не может быть определен во время компиляции. Однако, когда я пытаюсь скомпилировать это с помощью g ++, он работает отлично. Теперь я могу понять, что, вероятно, произошло здесь - компилятор заметил, что я вызываю эту функцию только после передачи константы времени компиляции в качестве параметра. Некоторые серьезные оптимизаций здесь происходит ... Но когда я пытаюсь скомпилировать это с помощью MSVC++ 2008, я получаю это:

1>c:\prj\test\test.cpp(15) : error C2057: expected constant expression 
1>c:\prj\test\test.cpp(15) : error C2466: cannot allocate an array of constant size 0 
1>c:\prj\test\test.cpp(15) : error C2133: 'iTest' : unknown size 

Мой вопрос: как это соответствует определению языка (С стандарт (стандарт C++))? Хорошо ли для g ++ делать такую ​​оптимизацию (что в этом случае легко увидеть, но в первый раз я столкнулся с ней, это было в большом проекте, и на первый взгляд это не имело большого смысла).

+0

Возможный дубликат [Массивы переменной длины в C++?] (Http://stackoverflow.com/questions/1887097/variable-length-arrays-in-c) –

ответ

5

C99 (самая последняя версия стандарта C) позволяет создавать массивы с динамическим размером. Однако эта функция не поддерживается Visual Studio (которая реализует только поддержку C89)

В C++ это не так и, вероятно, никогда не будет действительным.

+0

Почему это никогда не будет действительным в C++? Компилятор просто должен настроить указатель стека, инициализировать все с помощью конструктора по умолчанию и убедиться, что он очищается при выходе из области, правильно? Нелегко, но не невозможно. Он уверен, что использует 'alloca()'. –

+0

Jalf сказал, что «вероятно, никогда не будет действительным», и хорошая причина думать, что комитет C++ только что закончил писать стандарт для следующей версии C++, они определенно рассмотрели все функции, добавленные C на C99, и VLA weren Не принято. См. Также http://stackoverflow.com/questions/1887097/variable-length-arrays-in-c –

+1

Как сказал @Ben, он был отклонен для предстоящего C++ 0x, поэтому им пришлось бы отменить это решение в чтобы добавить его позже. И это просто не так необходимо в C++, как и в C. C++ уже имеет 'std :: vector', который решает многие из тех же проблем. В C++ требуется меньше VLA. – jalf

2

Массивы с динамическим размером являются особенностью C99. Если ваш компилятор поддерживает C99 (GCC делает, VC не полностью) - и если вы выбросите переключатель C99, то это скомпилируется.

0

Это не стандарт C++ (но стандарт C). Реализации могут предоставить alloca (или _alloca с msvc), который в значительной степени выполняет работу.