Форум программистов, компьютерный форум CyberForum.ru

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 9, средняя оценка - 4.89
alsav22
5416 / 4812 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
#1

С++ VLA и прочее... - C++

30.11.2012, 00:17. Просмотров 1304. Ответов 51
Метки нет (Все метки)

 Комментарий модератора 
Перенесено из Порекомендуйте компилятор


Dev-C++ меня удивляет. Вот такой код компилирует без ошибок и предупреждений:
C++
1
2
3
4
5
6
7
int main()
{
    int m;
    int arr[m];
    
    return 0;
}
А такой и выполняет:
C++
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
using namespace std;
 
int main()
{
    int m;
    cin >> m;
    int arr[m];
    
    return 0;
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
30.11.2012, 00:17     С++ VLA и прочее...
Посмотрите здесь:

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

Рекурентная формула и прочее - C++
Добрый день , пишу вам для получения помощи! Никак не могу сделать рекурентную формулу и программу под выражением &quot;б&quot;Помогите...

Дирректива define и прочее - C++
Помогите пожалуйста решить задание, никогда раньше с такими не сталкивался! =( 1) Даны целые числа x, у и вещественное число z....

Указатель на массив char и прочее - C++
Страуструп для проверки прочитанного в заданиях после одной из глав просит через typedef сделать пару объявлений и вот как делать некоторые...

Размер примитивных типов, выравнивание и прочее - C++
Как обычно борются с тем, что примитивный тип от компа к компу разного размера? Допустим, если записывают данные по сети или в двоичные...

Инкремент, декремент и прочее. A+++ - что означают это три плюса - C++
день добрый х) в задании попалась такая операция: a+++ = b%2 так вот. что, собственно, означают это три плюса?я знаю что есть инкремент, но...

Для чего нужны переменные, и прочее типа, константа, типы , массивы и т.к.д ? - C++
Для чего нужны переменные, и прочее типа, константа, типы , массивы и т.к.д

После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
kravam
быдлокодер
1693 / 880 / 44
Регистрация: 04.06.2008
Сообщений: 5,438
01.12.2012, 01:37     С++ VLA и прочее... #31
Цитата Сообщение от alsav22 Посмотреть сообщение
то зачем компилятору знать его размер?
компилятору необязательно знать его размер; выделяется память как мы выяснили на стадии выполнения и увеличиваемый размер тоже узнаётся на стадии выполнения. И компилятор в этот момент спит спокойным сном, а программа работает.

А вообще противоречий здравому смыслу много. Сделали и сделали, забей. Может, исправятся когда...
alsav22
5416 / 4812 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
01.12.2012, 02:10  [ТС]     С++ VLA и прочее... #32
Цитата Сообщение от kravam Посмотреть сообщение
Выделение памяти под массив и его инициализация происходят между точкой входа и ret, значит в main
Сейчас почитал цитаты, где говорится о выделении памяти. Нигде не говорится, что память выделяется до входа в main(). Везде, или до начала работы main(), или до выполнения кода main(). А как это трактовать неизвестно. Одни так трактуют, другие иначе. Наверное, всё упирается в точное определение: что считать началом выполнения кода функци, вход в main() или что-то другое. Если бы это определение было, то и спорить было бы не о чем.
kravam
быдлокодер
1693 / 880 / 44
Регистрация: 04.06.2008
Сообщений: 5,438
01.12.2012, 03:34     С++ VLA и прочее... #33
Цитата Сообщение от alsav22 Посмотреть сообщение
Наверное, всё упирается в точное определение: что считать началом выполнения кода функци, вход в main() или что-то другое. Если бы это определение было, то и спорить было бы не о чем.
начало функции main это точка входа в main, это одно и то же, узнаётся так:

C++
1
2
3
4
5
6
7
#include <stdio.h>
int main()
{
    printf ("%x\n", main);
    getchar ();
    return 0;
}
А вообще смотри, ты говоришь о статических массивах а в пример приводишь локальные и мы все за тобой как попугаи повторяем, с самого начала темы и той и другой. Несём какую-то херь, а того не замечаем что
C++
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
using namespace std;
 
int main()
{
    int m;
    cin >> m;
    int arr[m];
    
    return 0;
}
Так-то разобраться, это не статический массив, а локальный. Ибо определён в функции. Ну и что, что она называется main, она ничем от других функций не отличается кроме того, что начинает выполняться первой. Всё предсказуемо, обыкновенное выделение памяти локального массива.

++++++++++++++++++++++++++++++++++++++++++++++++++++++

А статический-то массив вот он:
C++
1
2
3
4
5
6
7
#include <stdio.h>
int m;
int arr[m];
int main()
{
    return 0;
}
И m тут по-любому должна быть известна до выполнения main; на такой код как раз компилятор и ругнётся.
Такие дела.
Цитата Сообщение от alsav22 Посмотреть сообщение
Всё. Окончательно запутался.
теперь-то распутался?

Добавлено через 29 минут
Или. что то же самое:
C++
1
2
3
4
5
6
7
#include <stdio.h>
int main()
{
int m;
static int arr[m];
return 0;
}
или
C++
1
2
3
4
5
6
7
8
9
10
void foo () {
int m;
static int arr[m];
return 0;
}
 
int main()
{
 return 0;
}
На всё это компилятор ругается.
alsav22
5416 / 4812 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
01.12.2012, 04:29  [ТС]     С++ VLA и прочее... #34
Цитата Сообщение от kravam Посмотреть сообщение
А вообще смотри, ты говоришь о статических массивах а в пример приводишь локальные и мы все за тобой как попугаи повторяем, с самого начала темы и той и другой
Я согласен с этим твоим постом: Размер статического массива Спорить не берусь, но по моему, такое название допустимо. Это всё равно, что статическое и динамическое связывание. К классу памяти это не имеет отношения.
Миниатюры
С++ VLA и прочее...  
alsav22
5416 / 4812 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
01.12.2012, 05:04  [ТС]     С++ VLA и прочее... #35
Цитата Сообщение от kravam Посмотреть сообщение
начало функции main это точка входа в main, это одно и то же
Я же пишу, что
Сейчас почитал цитаты, где говорится о выделении памяти. Нигде не говорится, что память выделяется до входа в main(). Везде, или до начала работы main(), или до выполнения кода main(). А как это трактовать неизвестно. Одни так трактуют, другие иначе. Наверное, всё упирается в точное определение: что считать началом выполнения кода функци, вход в main() или что-то другое. Если бы это определение было, то и спорить было бы не о чем.
Обрати внимание, нигде не упоминается ни вход в main(), ни начало main(). А о том как понимать, например, начало работы main() можно спорить до бесконечности. Ты будешь говорить, что вход в main() и есть начало работы main(), другой будет доказывать, что начало работы - это выполнение первой прописаной в main() инструкции, третий ещё что-нибудь. Если я правильно понял (если нет - поправь), то выделение памяти происходит при входе в main(), но до выполнения первой инструкции прописанной в main() в коде.

Добавлено через 10 минут
Цитата Сообщение от kravam Посмотреть сообщение
теперь-то распутался?
Нет. Получается, что локальный массив, объявленный в main(), ничем не отличается от динамического. И размер ему можно задавать во время выполнения программы, и жить он будет до конца программы, только память под ним нельзя освободить.

Добавлено через 4 минуты
Цитата Сообщение от kravam Посмотреть сообщение
На всё это компилятор ругается.
У меня даже это не скомпилирует:
C++
1
2
3
4
5
6
7
int main()
{
 int m = 10;
 int arr[m];
 
 return 0;
}
Подавай ему const int m = 10.
alsav22
5416 / 4812 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
01.12.2012, 09:29  [ТС]     С++ VLA и прочее... #36
Вот что в литературе.
Миниатюры
С++ VLA и прочее...   С++ VLA и прочее...   С++ VLA и прочее...  

С++ VLA и прочее...   С++ VLA и прочее...   С++ VLA и прочее...  

Jupiter
01.12.2012, 10:41
  #37

Не по теме:

Цитата Сообщение от MrGluck Посмотреть сообщение
Но gcc умеет корректно обрабатывать данные запросы, приводя к константе размер массива на момент создания. А учитывая, что никаких плохих последствий из этого не выходит, можно предположить, что данное поведение будет узаконено в будущих стандартах С++ (все же в стандарт С подобную фичу включили).
не надо нам VLA! это зло

kravam
быдлокодер
1693 / 880 / 44
Регистрация: 04.06.2008
Сообщений: 5,438
01.12.2012, 10:59     С++ VLA и прочее... #38
Цитата Сообщение от alsav22 Посмотреть сообщение
Обрати внимание, нигде не упоминается ни вход в main(), ни начало main(). А о том как понимать, например, начало работы main() можно спорить до бесконечности. Ты будешь говорить, что вход в main() и есть начало работы main(), другой будет доказывать, что начало работы - это выполнение первой прописаной в main() инструкции, третий ещё что-нибудь.
для того, чтобы узнать адрес функции, есть такой код:
C++
1
2
3
4
5
6
7
#include <stdio.h>
int main()
{
    printf ("%x\n", main);
    getchar ();
    return 0;
}
. Это адрес функции или, что то же самое, её начало. Адрес первой АССЕМБЛЕРНОЙ инструкции, если угодно. Я не буду спорить если кто-то скажет что нет, не это начало, на фиг надо нервы трепать.
...Кстати, да, вот тут Evg договорился до начала main. Видишь, я тоже поднимал (и поднимаю) подобные вопросы
Почему глобальный объект, объявленный до main, конструируется в ней?


++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Цитата Сообщение от alsav22 Посмотреть сообщение
Если я правильно понял (если нет - поправь), то выделение памяти происходит при входе в main(), но до выполнения первой инструкции прописанной в main() в коде.
Нет. Мы входим в функцию main, мы никак не можем миновать первую инструкцию. Вот здесь чётко показано, вот функция main, она ограничена слева жирной скобкой.
http://www.cyberforum.ru/attachment....8&d=1354307130


1) Первая инструкция main Это PUSH EBP (подсвечена)
2) блаблабла
3) Инструкция, которая выделяет память SUB ESP, 34
4) блаблабла
5) Инструкция, которая кладёт в выделеную память строку "rrrrr....."REP MOVS BYTE блаблабла

Цитата Сообщение от alsav22 Посмотреть сообщение
Нет. Получается, что локальный массив, объявленный в main(), ничем не отличается от динамического. И размер ему можно задавать во время выполнения программы, и жить он будет до конца программы, только память под ним нельзя освободить.
Так и получается. Это скорее хорошо, чем плохо. Вот тут MrGluck попытался это объяснить
Порекомендуйте компилятор

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

На счёт всего остального- я не знаю что и сказать. Все пишут как "должно быть", но преподносят это "как есть". А его нет, сам же видел, оно просто должно быть. С другой стороны если по стандарту описано, что для "нединамических" массивов память должна быть известна заранее, авторы так и напишут, согласен? Вот и всё.
И кстати, тот же Стивен Прата (в той же книге "Статический класс памяти, внешнее связывание", таблица 9.1) определяет "статический" класс памяти не как "нединамический", а как либо объявленый с ключевым словом static, либо как объявленный вне функции, это то, о чём я написал в предыдущем посту и это то, чему не соответствует твоя цитата.
Порекомендуйте компилятор
Кто прав в этом случае я решил для себя. По-моему Прата убедительнее.

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Как видишь, есть противоречия между всем и всем. Но что делать? Надо двигаться вперёд; где-то напролом, где-то как. Периодически возвращаясь к этому нерешённому вопросу, коих будет ещё очень много. Однажды решишь эти вопросы не абсолютно, но ДЛЯ СЕБЯ и скажешь:

"Колея это только моя, выбирайтесь своей колеёй".
В. Высоцкий.
alsav22
5416 / 4812 / 442
Регистрация: 04.06.2011
Сообщений: 13,587
01.12.2012, 20:04  [ТС]     С++ VLA и прочее... #39
Цитата Сообщение от kravam Посмотреть сообщение
Это адрес функции или, что то же самое, её начало. Адрес первой АССЕМБЛЕРНОЙ инструкции, если угодно.
Это я понимаю. Я другую инструкцию имею ввиду. Цитирую себя:
Цитата Сообщение от alsav22 Посмотреть сообщение
Если я правильно понял (если нет - поправь), то выделение памяти происходит при входе в main(), но до выполнения первой инструкции прописанной в main() в коде.
Имею ввиду первую написанную инструкцию в исходнике. Например, код:
C++
1
2
3
4
5
6
7
int main()
{
    cout << "Entry;
    int m = 3;
    cout << m;
    return 0;
}
Выделение памяти произойдёт при входе в main() до выполнения первой инструкции в тексте кода:
C++
1
cout << "Entry;
Так?

Цитата Сообщение от kravam Посмотреть сообщение
И кстати, тот же Стивен Прата (в той же книге "Статический класс памяти, внешнее связывание", таблица 9.1) определяет "статический" класс памяти не как "нединамический", а как либо объявленый с ключевым словом static, либо как объявленный вне функции, это то, о чём я написал в предыдущем посту и это то, чему не соответствует твоя цитата.
Порекомендуйте компилятор
Кто прав в этом случае я решил для себя. По-моему Прата убедительнее.
Тут спорить не буду, просто повторю, что я имел ввиду не класс памяти, а употребляемое (не только мною) название для массива, размер которого известен (или должен быть известен (уже и не знаю, как писать)) на этапе компиляции. Слово одно, но в разных случаях - разные значния. Тот же Прата о статическом и динамическом связывании (скрин). Согласен, что путаница некая есть. Лучше, конечно, называть просто: локальный массив.
Миниатюры
С++ VLA и прочее...  
alsav22
01.12.2012, 20:23  [ТС]
  #40

Не по теме:

Прошу прощения, кавычки в коде пропустил. Не успел исправить.

activnaya
255 / 45 / 2
Регистрация: 24.11.2012
Сообщений: 466
01.12.2012, 20:23     С++ VLA и прочее... #41
Цитата Сообщение от Jupiter Посмотреть сообщение
не надо нам VLA! это зло
в cstyle нужен. Однако вспомним что с++ это ООП и такой класс скомпилируется, но работать не будет.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class A
{
public:
    int array[];
    uint32_t siz;
 
    A(uint32_t s)
    {
        siz = s;
        array[ siz ];
 
        for (uint32_t i = 0; i < siz; ++i)
            array[ i ] = i;
    }
 
    ~A(){}
 
    uint32_t size() { return siz; }
 
    void print()
    {
        for (uint32_t i = 0; i < siz; ++i)
            std::cout << std::setw(3) << array[ i ];
    }
 
};
Поэтому используя ООП нам не удастся создать элемент класса с использованием VLA, а вот создание локального массива с использованием VLA имеет смысл.
MrGluck
Модератор
Эксперт CЭксперт С++
7178 / 4344 / 634
Регистрация: 29.11.2010
Сообщений: 11,822
01.12.2012, 20:33     С++ VLA и прочее... #42
Лично мое мнение, что массивы для сей, а там и VLA есть. В С++ можно с радостью использовать вектора и проблем не знать.
activnaya
255 / 45 / 2
Регистрация: 24.11.2012
Сообщений: 466
01.12.2012, 20:36     С++ VLA и прочее... #43
а как же кампатибл, энивэй что есть в сях, есть в плюсах.
kravam
быдлокодер
1693 / 880 / 44
Регистрация: 04.06.2008
Сообщений: 5,438
01.12.2012, 20:40     С++ VLA и прочее... #44
Цитата Сообщение от alsav22 Посмотреть сообщение
Выделение памяти произойдёт при входе в main() до выполнения первой инструкции в тексте кода:
По моему разумению всё должно идти своим чередом, инструкция за инструкцией. То есть сперва печать "Entry", потом выделение памяти под "m", потом инициализация "m", потом печать "m". Посмотрим в отладчике. С cout тяжело отследить, а с printf легко

C++
1
2
3
4
5
6
7
8
9
10
#include <iostream>
#include <stdio.h>
using namespace std;
 
int main() { 
 cout << "Entry"; 
 int m = 3; 
 printf ("%d", m); 
 return 0; 
}
отследил, было так: сперва выделение памяти X, потом печать "Entry", потом занесение в X-> 3, потом выделение памяти Y, потом занесение в Y->3, потом печать "m". Причём при печати "m" использовалось значение ячейка памяти Y а не X.

Цитата Сообщение от alsav22 Посмотреть сообщение
Выделение памяти произойдёт при входе в main() до выполнения первой инструкции в тексте кода:
ну то есть в данном конкретном случае выделение памяти и инициализация произошло как до так и после печати "Entry". Фактически в main под переменную "m" было выделено две ячейки памяти. Учитывая, что при печати "m" использовалась ячейка памяти Y, я бы сказал что после. А зачем комплятор придумал занесение X-> 3 (до печати "Entry") я не знаю и знать не хочу

Зачем тебе вообще это? Ну если так надо знать, сходи на wasm.ru, там в раздел "исследование программ", там научат работать с отладчиком. А то я закалебусь смотреть постоянно.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
01.12.2012, 20:40     С++ VLA и прочее...
Еще ссылки по теме:

Связка БД и прочее - MS Access
Здравствуйте. Я впервые занимаюсь БД и мне хотелось бы узнать, как осуществить следующее: Например создание БД для железнодорожных касс....

Массивы и прочее - C#
До сессии осталось совсем немного, прошу помощи по решению 3 задач, очень надеюсь что поможите... 1. В числовую переменную вводится...

VersionInfo и прочее - Visual C++
Никогда такого не делал, как задать версию проекта, название и прочее, что отображается в свойствах файла? Я так понимаю нужно вертеть с...

Календарь и прочее (=() JS - JavaScript
Здравствуйте уважаемые, поогите пожалуйста, есть код который виводит количество субод для определенного месяца. А мне нужно что б ввел год...

Массивы и прочее. - Turbo Pascal
1.Написать программу на Паскале которая должна находить сумму элементов в двухмерном массиве (размерностью 5 Х 5) случайных чисел в...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
MrGluck
Модератор
Эксперт CЭксперт С++
7178 / 4344 / 634
Регистрация: 29.11.2010
Сообщений: 11,822
01.12.2012, 20:40     С++ VLA и прочее... #45
activnaya, так он и есть. VS не поддерживает стандарт C99, VLA на С и С++ нет. gcc (MinGW) поддерживает C99. VLA есть и в С и в С++, хоть последнее и не по стандарту.
Yandex
Объявления
01.12.2012, 20:40     С++ VLA и прочее...
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru