Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > C/C++ программирование > Общие вопросы C/C++
Регистрация

Восстановить пароль

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 12.01.2014, 11:09   #1
MooNDeaR
В стагнации
Участник клуба
 
Аватар для MooNDeaR
 
Регистрация: 29.07.2011
Сообщений: 1,303
По умолчанию Странное поведение компилятора Linux [g++]

Сегодня обнаружил крайне забавную ведь в компиляторе g++ v4.7.3 под Linux.

Есть вот такой код:

Код:
int main()
{
    int n = 2;
    int b = 7;

    n += b;

    int c[n];

    for(int i = 0; i < n; ++i)
    {
        c[i] = i + 1;
    }
    for(int i = 0; i < n; ++i)
        cout << c[i] << endl;

    return 0;
}
Компилирую его вот так:

Код:
:~$ g++ main.cpp -o test
И он компилируется! Без всяких проблем. В консоль выдает следующее



Но как так?! Он не должен работать. Подумал, что он автоматически создает динамический массив, но нет.

Код:
delete[] c; //SEGABRT - во время исполнения
Если написать так:

Код:
int c[n] = {0}
То получаю ошибку во время компиляции:
Цитата:
main.cpp:13:18: error: variable-sized object ‘c’ may not be initialized
И вот я что-то впервые слышу о всяких там variable-sized object. Может я что-то упустил за последние годы?
E-mail: pashaworking@gmail.com | ICQ: 479914426 | Skype: moondearr
Понять, чего от тебя требует заказчик – это уже половина всей работы, а иногда и полностью выполненное задание.
MooNDeaR вне форума Ответить с цитированием
Старый 12.01.2014, 11:12   #2
Stilet
Белик Виталий :)
Старожил
 
Аватар для Stilet
 
Регистрация: 23.07.2007
Сообщений: 57,097
По умолчанию

Цитата:
динамический массив
А где у тебя тут динамический массив?
Ты имеешь ввиду что без const int компиль создал массичик из n элементов. и это тебя удивило?
I'm learning to live...
Stilet вне форума Ответить с цитированием
Старый 12.01.2014, 11:15   #3
MooNDeaR
В стагнации
Участник клуба
 
Аватар для MooNDeaR
 
Регистрация: 29.07.2011
Сообщений: 1,303
По умолчанию

Цитата:
и это тебя удивило?
Меня удивило то, что по стандарту С++98 размер статического массива нельзя задавать переменной. Только константным выражением!

В винде, например, компилятор студии выдает это:
Цитата:
error C2057 expected constant expression
E-mail: pashaworking@gmail.com | ICQ: 479914426 | Skype: moondearr
Понять, чего от тебя требует заказчик – это уже половина всей работы, а иногда и полностью выполненное задание.
MooNDeaR вне форума Ответить с цитированием
Старый 12.01.2014, 11:32   #4
halcyon
crafter
Форумчанин
 
Аватар для halcyon
 
Регистрация: 03.09.2011
Сообщений: 127
По умолчанию

Цитата:
Сообщение от Stilet Посмотреть сообщение
А где у тебя тут динамический массив?
Ты имеешь ввиду что без const int компиль создал массичик из n элементов. и это тебя удивило?
Да, это странно.
halcyon вне форума Ответить с цитированием
Старый 12.01.2014, 11:49   #5
ROD
Linux C++ Qt ARM
Старожил
 
Аватар для ROD
 
Регистрация: 30.11.2008
Сообщений: 3,030
По умолчанию

Ну во-первых, v4.7.3 работает по стандарту C++11 (правда не полностью). Хотя скорее всего это просто особенность этого компилятора, не продиктованная стандартом.

А во-вторых - если учесть, что в начале программы n получает вполне однозначное значение и больше нигде никак не изменяется, компилятор, скорее всего, b вообще выкинул, а n заменил на константу.
Дилетант широкого профиля.

"Слова ничего не стоят - покажите мне код!" © Линус Торвальдс
ROD вне форума Ответить с цитированием
Старый 12.01.2014, 12:04   #6
MooNDeaR
В стагнации
Участник клуба
 
Аватар для MooNDeaR
 
Регистрация: 29.07.2011
Сообщений: 1,303
По умолчанию

Цитата:
Ну во-первых, v4.7.3 работает по стандарту C++11 (правда не полностью).
Для компиляции по этому стандарту, есть специально задаваемый флаг --std=c++11, если явно задать --std=c++98, всё равно будет работать.

Цитата:
А во-вторых - если учесть, что в начале программы n получает вполне однозначное значение и больше нигде никак не изменяется...
Код:
n += b;
Но ладно бы это было так. Я и b изменял после и n. Если посмотреть на код после препроцессора (параметр -E у компилятора), то код не изменяется никак. Как посмотреть на код после всех оптимизаций, я не знаю, но хотел бы узнать.

Цитата:
скорее всего это просто особенность этого компилятора, не продиктованная стандартом.
Дык это же меняет столько вещей! Во многих местах теперь можно забить на создание более медлительных динамических массивов и использовать статические. Например, когда нам нужен буферный массив, но заранее нам его размер не известен.
E-mail: pashaworking@gmail.com | ICQ: 479914426 | Skype: moondearr
Понять, чего от тебя требует заказчик – это уже половина всей работы, а иногда и полностью выполненное задание.

Последний раз редактировалось MooNDeaR; 12.01.2014 в 12:25.
MooNDeaR вне форума Ответить с цитированием
Старый 12.01.2014, 12:20   #7
ROD
Linux C++ Qt ARM
Старожил
 
Аватар для ROD
 
Регистрация: 30.11.2008
Сообщений: 3,030
По умолчанию

Цитата:
Если посмотреть на код после препроцессора (параметр -E у компилятора), то код не изменяется никак. Как посмотреть на код после всех оптимизаций, я не знаю, но хотел бы узнать.
Видимо никак не посмотреть, ну или я плохо гуглил. Надо в дизассемблере посмотреть что внутри программы получается.
Дилетант широкого профиля.

"Слова ничего не стоят - покажите мне код!" © Линус Торвальдс
ROD вне форума Ответить с цитированием
Старый 12.01.2014, 12:25   #8
MooNDeaR
В стагнации
Участник клуба
 
Аватар для MooNDeaR
 
Регистрация: 29.07.2011
Сообщений: 1,303
По умолчанию

Цитата:
Надо в дизассемблере посмотреть что внутри программы получается.
Сделал так:
Код:
int fun(int n, int b)
{
    n += b;

    int buf[n][b];

    for(int i = 0; i < n; ++i)
    {
        for(int j = 0; j < b; ++j)
            buf[i][j] = i + 1;
    }
    for(int i = 0; i < n; ++i)
    {
        for(int j = 0; j < b; ++j)
            cout << buf[i][j] << ' ';
        cout << endl;
    }
    return n + b;
}

int main()
{
    int x, y;
    cin >> x >> y;
    cout << fun(x,y) << endl;

    return 0;
}
Теперь он точно ни b, ни n удалить не может и на константы не заменит...
E-mail: pashaworking@gmail.com | ICQ: 479914426 | Skype: moondearr
Понять, чего от тебя требует заказчик – это уже половина всей работы, а иногда и полностью выполненное задание.
MooNDeaR вне форума Ответить с цитированием
Старый 12.01.2014, 12:33   #9
ROD
Linux C++ Qt ARM
Старожил
 
Аватар для ROD
 
Регистрация: 30.11.2008
Сообщений: 3,030
По умолчанию

Хм... а вот тут... у меня даже допотопный borland C++ builder 3.11 позволял в "других" функциях задавать размер "статичного" массива параметрами, передаваемыми функции. Надо смотреть что компилятор на самом деле делает.
Дилетант широкого профиля.

"Слова ничего не стоят - покажите мне код!" © Линус Торвальдс
ROD вне форума Ответить с цитированием
Старый 12.01.2014, 13:57   #10
pproger
C++ hater
Старожил
 
Аватар для pproger
 
Регистрация: 19.07.2009
Сообщений: 3,333
По умолчанию

2MooNDeaR
массивы переменной длины в крестах - это расширение гсс (во всяком случае до стандарта с++03). чтобы компилять стандартом с++98 и игнорировать все расширения нужно писать так:
g++ -std=c++98 -pedantic-errors main.cpp
I invented the term Object-Oriented, and I can tell you I did not have C++ in mind. (c)Alan Kay

My other car is cdr.

Q: Whats the object-oriented way to become wealthy?
A: Inheritance
pproger вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
странное поведение компилятора Kukurudza Общие вопросы C/C++ 10 23.09.2011 08:22
Странное поведение realloc eraserhp Помощь студентам 0 15.05.2010 18:06
Странное поведение gets alex_alpha Общие вопросы C/C++ 3 27.03.2010 18:21
Странное поведение процедуры Sergey1974 Общие вопросы Delphi 2 11.12.2009 21:41