1 | |||||||||||
[Задача] Объясните результат исполнения программы10.10.2011, 18:04. Показов 11224. Ответов 21
Метки задачи от evg (Все метки)
Код
$ g++ t1.cc t2.cc $ ./a.out 20
7
|
10.10.2011, 18:04 | |
Ответы с готовыми решениями:
21
Объясните результат работы следующей программы Объясните пожалуйста результат работы программы Как вывести результат исполнения этой программы? Объясните разницу во времени исполнения кода |
448 / 211 / 21
Регистрация: 07.10.2011
Сообщений: 462
|
|
10.10.2011, 18:13 | 2 |
а если порядок файлов в строке
g++ t1.cc t2.cc поменять?
0
|
186 / 186 / 21
Регистрация: 08.01.2011
Сообщений: 1,139
|
|
10.10.2011, 18:35 | 3 |
В Visual studio 2008 ошибка компиляции. Два раза написан метод get.
Или я не понял о чем вы?
0
|
Модератор
12453 / 7478 / 1752
Регистрация: 25.07.2009
Сообщений: 13,748
|
|
10.10.2011, 19:21 | 4 |
Evg, и действительно, как это оно у Вас вообще скомпилировалось?
Код
$ g++ -o t t1.cc t2.cc /cygdrive/c/DOCUME~1/andrew/LOCALS~1/Temp/ccPKWOoS.o:t2.cc:(.text+0x0): multiple definition of `C::get()' /cygdrive/c/DOCUME~1/andrew/LOCALS~1/Temp/cct23V89.o:t1.cc:(.text$_ZN1C3getEv[C: :get()]+0x0): first defined here collect2: ld returned 1 exit status
0
|
Временно недоступен
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
|
||||||
10.10.2011, 19:28 | 5 | |||||
У меня тоже всё компилируется, и тоже выводит 20
Забавно. Причем если main перенести в другую единицу трансляции, ничего не меняется. И ещё вот параллельно возник такой вопрос (меняем только t1.сс:
0
|
Модератор
12453 / 7478 / 1752
Регистрация: 25.07.2009
Сообщений: 13,748
|
|
10.10.2011, 19:36 | 6 |
Ага... На бсде тоже скомпилировалось и тоже 20 вывело...
Код
[andrew@server2 ~/bin]$ g++ -o t t1.cc t2.cc [andrew@server2 ~/bin]$ ./t 20
0
|
Временно недоступен
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
|
|
10.10.2011, 19:51 | 7 |
Странно, когда перенёс x в public, один раз таки выдало 10...
Такое ощущение, что при вызове c.get() вызывается конструктор объекта класса из t2.cc
0
|
10.10.2011, 20:27 [ТС] | 8 | ||||||||||
Сообщение было отмечено как решение
Решение
От порядка не зависит
Это implementation-dependend фича. Точнее, с точки зрения стандарта в тесте undefined behaviour, но как оно себя проявит - зависит от технических особенностей компилятора. Конкретно в данном случае в linux'е используется бинарный формат elf, а потому компилятор настроен одним образом. В винде используется более допотопный формат файла, из-за которого компиляторы настраиваются по другому В твоём случае тоже винда Добавлено через 3 минуты Тест представляет собой сокращённый тестовый пример, об который конкретно споткнулись в реальной жизни: в программу локально включили описание класса, имя которого (и имя метода), как оказалось, совпало с уже существующим, но продвинутый gcc оказался бессилен с точки зрения диагностики ошибки. Вероятность таким образом вляпаться не такая уж и большая, но, как показала практика, она отлична от нуля Добавлено через 7 минут Упрощённый вариант двух файлов с той же выдачей:
3
|
237 / 210 / 29
Регистрация: 08.06.2011
Сообщений: 467
|
||||||
10.10.2011, 20:39 | 9 | |||||
компилятор определяет
1
|
11.10.2011, 10:43 [ТС] | 10 |
Сообщение было отмечено как решение
Решениеобъяснение
Всё растёт из того, что стандарт Си++ требует того, чтобы inline-функции были multiply defined. Об этом я пояснял в Зачем нужен inline посты 6 и 11. Метод функции, описанный внутри тела класса, всегда является inline, даже если явно это не написано. gcc под системами с поддержкой elf'а реализует это свойство через weak-символы. В данном примере в первом файле мы имеем метод или функцию, определённую как weak, а во втором файле - метод или функцию с тем же манглированным именем, но уже честный global. Итого на линковке получается, что при разрешении ссылок global всегда перебивает weak
С нуля понять что такое weak несколько сложно, в своё время пояснял на более-менее живом примере: https://www.cyberforum.ru/cpp-... 46472.html Добавлено через 5 минут Как-то сумбурно пояснил, но для доходчивого пояснения надо рассказать про слишком многие вещи Добавлено через 4 минуты В догонку к пояснению
gcc через примерно такой же способ реализует шаблоны. Все шаблонные функции и переменные являются weak'ами, а потому когда они цепляются из инклюдов, то в каждом модуле получается функция с одним и тем же именем. Но за счёт weak'а на линковке отбрасывается всё, кроме одного экземпляра. А вот если есть специализация, то она строится как global, а потому перебивает все weak'и. И две специализации уже сделать нельзя, потому как два global'а уже конфликтуют друг с другом
Добавлено через 10 часов 25 минут Совсем забыл, что про inline я уже как-то рассказывал. См. Неочевидные ответы на простые вопросы раздел 7.2
14
|
22.11.2011, 13:38 [ТС] | 12 |
Объект определён ровно один раз. А два раза определён метод. Если ты два раза напишешь функцию на Си, то у тебя поломается на линковке. А здесь исходник содержит ошибку, но на линковке ошибка не проявилась. Так вот устроен язык Си++, что некоторые из реалиаций языка оказываются ненадёжными в этом плане. Потому что придумать язык мало, надо ещё и понимать, как будет работать компилятор с него и какие при этом могут оказаться подводные камни
0
|
Заблокирован
|
|
22.11.2011, 18:22 | 13 |
Ну уж не знаю, каким Вы компилятором пользуетесь, но я все таки не поленился перекопировал код Вашей так называемой ошибки и вот, что выдает VS2010
Ошибка 1 error LNK2005: "public: int __thiscall C::get(void)" (?get@C@@QAEHXZ) уже определен в c22.obj c:\Users\...\documents\visual studio 2010\Projects\ErrProj\ErrProj\ErrProj.obj Ошибка 2 error LNK1169: обнаружен многократно определенный символ - один или более c:\users\...\documents\visual studio 2010\Projects\ErrProj\Debug\ErrProj.exe 1 Так что никакаяя это не трудноуловимая ошибка, а сечется компилятором влегкую.
0
|
5055 / 3115 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
|
|
22.11.2011, 19:10 | 14 |
0
|
23.11.2011, 10:43 [ТС] | 18 |
Пока сентенция сводится к тому, что виндузовые компиляторы ругаются на линковке, а юниксовые - нет. Потому что там и там используются разный формат исполняемого файла, и под виндой, где используется более ущербный формат, не проходят такие финты ушами, которые возможны под юниксом.
Ну и так, для общего сведения. "g++" - это имя компилятора
1
|
28.11.2011, 01:16 | 19 |
подробнее изложи, в чем бОльшая ущербность формата. проиллюстрируй на примере этого случая. это интересно.
пока мне кажется все это раздражением при попытке завинтить шуруп с прямым шлицом крестообразной отверткой. формат то ли отвертки, то ли шурупа - определенно ущербный. об обобщении "виндузовые компиляторы". недавно было решено старый проект, сделанный под nt vs6 (mfc) развивать дальше ("ведь он уже есть, и успешно работает", почему не использовать оттуда куски, такой франкенштейн создать, и к нему осовремененного добавить, и будет хорошо). на то, чтобы сделать его компилируемым под vs2010, двое пахали одну неделю. потом еще столько же ушло на то, чтобы оно снова заработало. и бой продолжается. постепенно отрезаются омертвевшие части, заменяются новыми. затраты уже, по-моему, превысили затраты на новую разработку. а "всего лишь другой компилятор". и тоже виндоузовый.
0
|
28.11.2011, 11:03 [ТС] | 20 |
Это был всего лишь пас назад
Добавлено через 4 минуты Не поверишь, но в линуксе будет то же самое. И дело не только в компиляторе, но и в библиотеках и в интерфейсах операционной системы, и в изменившихся стандартах языка. То бишь на современной операционке скомпилять большую программу 10 летней давности (особенно если на Си++ написано) Это не обобщение, а эмпирическая сентенция на текущий момент. По результату того, где данный пример запускался. И дело не в компиляторе, а в том, как компилятор использует возможности бинарного формата, используемого в винде и в линухе
0
|
28.11.2011, 11:03 | |
28.11.2011, 11:03 | |
Помогаю со студенческими работами здесь
20
Результат исполнения функции Найти результат исполнения кода Как в C++ получить результат исполнения внешней команды В каком регистре будет находиться результат исполнения оператора add ax, bx Ошибки во время исполнения программы Разное время исполнения программы Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |