(Закрыто) [Отцам C++] set_new_handler
Тут я написал что-то плохое, потом дочитал твой пост до конца, одумался и стер
В STL есть алгоритм
$ ./a.out
memory exhausted after 7692 allocations!
Например, если в inline-функции есть локальная статическая переменная, и компилятор-таки соизволил сделать эту функцию inline, то статическая переменная... своя в каждой копии тела функции!Ты в этом уверен ? Это, кажется, противоречит стандарту. К тому же не воспроизводится.
using namespace std;
и почему стоит как можно реже прибегать к глобальным переменным глобального пространства имен.
using namespace std;
О да! Ненавижу эту строчку
Освежаю я тут, значит, свои знания C++ при помощи книги Б. Эккеля "Thinking in C++". Интересные вещи выясняются. Например, если в inline-функции есть локальная статическая переменная, и компилятор-таки соизволил сделать эту функцию inline, то статическая переменная... своя в каждой копии тела функции!Кто же тебя так жестоко обманул? Процитируй из чего такой вывод был сделан.
Из стандарта четко и однозначно следует, что локальная static-переменная - общая для всех вызовов функции вне зависимости от того инлайнится она или нет (и объявлена ли inline или нет).
И никто не мешает компилятору сделать её общей. Разве что яйца, но тогда это очень плохой компилятор =)
Разве что яйца, но тогда это очень плохой компилятор =)я бы даже сказал, что "тогда это не компилятор языка C++" - ибо противоречит стандарту оного.
у extern inline функций (или просто inline - без static) - локальная static переменная одна и та же во всех трансляциях программы,
у static inline функций - локальная static переменная одна и та же в пределах трансляции, а если в другой трансляции инклюдится определение той же static inline функции, то у нее будет уже другая локальная static переменная, но тоже единая в пределах трансляции.
все то же касается конечно и функций без inline.
Bruce Eckel, "Thinking in C++", 2nd ed. Volume 1, chapter 10 "Name Control", Static initialization dependency, What to do, Technique 2, самый последний абзац:
You might be tempted to write d1( ) and d2( ) as inline functions inside their respective header files, but this is something you must definitely not do. An inline function can be duplicated in every file in which it appears – and this duplication includes the static object definition. Because inline functions automatically default to internal linkage, this would result in having multiple static objects across the various translation units, which would certainly cause problems. So you must ensure that there is only one definition of each wrapping function, and this means not making the wrapping functions inline.Ага, тут я не совсем точно выразился - речь шла об inline-функциях в двух различных .cpp-модулях.
Всем большое спасибо! С вашими поправками и разъяснениями заработало. Даже Windows выругалась на недостаток виртуальной памяти.
Because inline functions automatically default to internal linkage, this would result in having multiple static objects across the various translation units, which would certainly cause problems.Если я все правильно понял, то согласно стандарту (ISO/IEC 14882-2003 параграфы 3.5, 7.1.2) у функций по умолчанию (т.е. пока не объявишь static) external linkage вне зависимости от того inline или нет. Так что ИМХО Эккель обманывает читателей. Есть правда оговорка, что среди повсеместно используемых компиляторов C++ в данный момент нет ни одного, совместимого со стандартом, поэтому логично ожидать, что по этому пункту в реальных компиляторах также будет несовместимость. Вероятно Эккель имел в виду распространенные реализации языка C++, а не сам язык C++.
Никого он не обманывает, он просто объясняет почему реализацию методов со статичными объектами не следует помещать в заголок. Слово «inline» там указует на способ размещения тела метода.
Никого он не обманывает, он просто объясняет почему реализацию методов со статичными объектами не следует помещать в заголок. Слово «inline» там указует на способ размещения тела метода.это и есть оговорки по поводу несовместимых реализаций (коих большинство)
поскольку согласно стандарту (1) не inline функции с external linkage должны быть определены только в одной трансляции (т.н. one definition rule - ISO/IEC 14882-2003 параграф 3.2 (2) inline функции с external linkage должны быть определены в каждой трансляции, которая их использует, т.е. как правило в заголовке. При этом: если функция с external linkage имеет локальную статическую переменную, то она является одним и тем же объектом для всех трансляций вне зависимости от того является ли эта функция inline, т.е. вне зависимости от того в скольких трансляциях она определена.
Эккель же обманывает (AFAIK когда прямым текстом утверждает, что inline функция по умолчанию имеет internal linkage (см. цитату) - это вероятно так и есть во многих реализациях, но AFAIK противоречит стандарту.
Все ссылки на стандарт даны в предыдущих постах.
Похоже, анахронизм в книжке.
Оставить комментарий
enochka1145
Освежаю я тут, значит, свои знания C++ при помощи книги Б. Эккеля "Thinking in C++". Интересные вещи выясняются. Например, если в inline-функции есть локальная статическая переменная, и компилятор-таки соизволил сделать эту функцию inline, то статическая переменная... своя в каждой копии тела функции!О чём это я?.. А, Bruce Eckel, Thinking in C++, Volume 1, chapter 13 "Dynamic Object Creation".
GCC 3.4.4 (CygWin-овский запускается из-под Eclipse CDT (завидно, да? код: В результате пишет не "memory exhausted after...", а Почему?
И ещё. На самом деле программа не компилируется. gcc не нравится использование count в main и out_of_memory. Пишет: Почему? Даже Eclipse CDT (ничто по сравнению с Eclipse JDT, для Java) мгновенно просекает что такое count и показывает своё понимание в тултипе. А мне приходится называть переменную coun вместо count, чтобы скомпилировать программу. Что не так? Это какая-то важная глобальная функция из заголовочных файлов - count, или gcc издевается?