Форум программистов, компьютерный форум, киберфорум
C++
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.55/55: Рейтинг темы: голосов - 55, средняя оценка - 4.55
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30

[Задача] Объясните результат исполнения программы

10.10.2011, 18:04. Показов 11965. Ответов 21

Студворк — интернет-сервис помощи студентам
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Файл t1.cc
#include <iostream>
 
class C
{
    int x;
 
  public:
    C() { x = 10; }
    int get() { return x; }
};
 
int main (void)
{
  C c;
 
  std::cout << c.get() << std::endl;
  return 0;
}
C++
1
2
3
4
5
6
7
8
9
10
11
// Файл t2.cc
class C
{
  public:
    int get();
};
 
int C::get()
{
  return 20;
}
Code
1
2
3
$ g++ t1.cc t2.cc
$ ./a.out
20
Задача из разряда "трудноуловимые ошибки"
7
Programming
Эксперт
39485 / 9562 / 3019
Регистрация: 12.04.2006
Сообщений: 41,671
Блог
10.10.2011, 18:04
Ответы с готовыми решениями:

Объясните результат работы следующей программы
double x =1.23456789; for(int i=0; i&lt;1030;i++) x=x/2; for( int i=0; i &lt;1030;i++) x=x*2; cout.precision (12); ...

Объясните пожалуйста результат работы программы
#include &lt;iostream&gt; using namespace std; int main() { short int i; short unsigned int j; j = 60000; ...

Как вывести результат исполнения этой программы?
Написал программу, она работает проверял в turbo debbuger. Но не могу понять как вывести результат исполнения этой программы. Помогите...

21
 Аватар для aeshes
448 / 211 / 21
Регистрация: 07.10.2011
Сообщений: 462
10.10.2011, 18:13
а если порядок файлов в строке
g++ t1.cc t2.cc
поменять?
0
186 / 186 / 21
Регистрация: 08.01.2011
Сообщений: 1,139
10.10.2011, 18:35
В Visual studio 2008 ошибка компиляции. Два раза написан метод get.
Или я не понял о чем вы?
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,977
10.10.2011, 19:21
Evg, и действительно, как это оно у Вас вообще скомпилировалось?
Code
1
2
3
4
5
6
$ 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
Временно недоступен
 Аватар для #pragma
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
10.10.2011, 19:28
У меня тоже всё компилируется, и тоже выводит 20
Забавно. Причем если main перенести в другую единицу трансляции, ничего не меняется.
И ещё вот параллельно возник такой вопрос (меняем только t1.сс:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
// Файл t1.cc
#include <iostream>
 
class C
{
    int x;
 
  public:
    C() { x = 10; }
    int get() { return x; }
};
 
int main (void)
{
  C c();
 
  std::cout << c.get() << std::endl;
  return 0;
}
Почему-то выдаёт ошибку error: request for member ‘get’ in ‘c’, which is of non-class type ‘C()’
0
Модератор
Эксперт PythonЭксперт JavaЭксперт CЭксперт С++
 Аватар для easybudda
12843 / 7592 / 1766
Регистрация: 25.07.2009
Сообщений: 13,977
10.10.2011, 19:36
Цитата Сообщение от #pragma Посмотреть сообщение
Забавно
Ага... На бсде тоже скомпилировалось и тоже 20 вывело...
Code
1
2
3
[andrew@server2 ~/bin]$ g++ -o t t1.cc t2.cc
[andrew@server2 ~/bin]$ ./t
20
Загадка...
0
Временно недоступен
 Аватар для #pragma
957 / 228 / 14
Регистрация: 12.04.2009
Сообщений: 926
10.10.2011, 19:51
Странно, когда перенёс x в public, один раз таки выдало 10...
Такое ощущение, что при вызове c.get() вызывается конструктор объекта класса из t2.cc
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
10.10.2011, 20:27  [ТС]
Лучший ответ Сообщение было отмечено как решение

Решение

Цитата Сообщение от aeshes Посмотреть сообщение
а если порядок файлов в строке
g++ t1.cc t2.cc
поменять?
От порядка не зависит

Цитата Сообщение от Chelioss Посмотреть сообщение
В Visual studio 2008 ошибка компиляции. Два раза написан метод get.
Или я не понял о чем вы?
Это implementation-dependend фича. Точнее, с точки зрения стандарта в тесте undefined behaviour, но как оно себя проявит - зависит от технических особенностей компилятора. Конкретно в данном случае в linux'е используется бинарный формат elf, а потому компилятор настроен одним образом. В винде используется более допотопный формат файла, из-за которого компиляторы настраиваются по другому

Цитата Сообщение от easybudda Посмотреть сообщение
Evg, и действительно, как это оно у Вас вообще скомпилировалось?
В твоём случае тоже винда

Добавлено через 3 минуты
Тест представляет собой сокращённый тестовый пример, об который конкретно споткнулись в реальной жизни: в программу локально включили описание класса, имя которого (и имя метода), как оказалось, совпало с уже существующим, но продвинутый gcc оказался бессилен с точки зрения диагностики ошибки. Вероятность таким образом вляпаться не такая уж и большая, но, как показала практика, она отлична от нуля

Добавлено через 7 минут
Упрощённый вариант двух файлов с той же выдачей:

C++
1
2
3
4
5
6
7
8
9
10
11
12
#include <iostream>
 
inline int func (void)
{
  return 10;
}
 
int main (void)
{
  std::cout << func() << std::endl;
  return 0;
}
C++
1
2
3
4
int func (void)
{
  return 20;
}
3
237 / 210 / 29
Регистрация: 08.06.2011
Сообщений: 467
10.10.2011, 20:39
Цитата Сообщение от #pragma Посмотреть сообщение
Почему-то выдаёт ошибку error: request for member ‘get’ in ‘c’, which is of non-class type ‘C()’
компилятор определяет
C++
1
C c();
как прототип функции, которая принимает void и возвращает объект типа C
1
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
11.10.2011, 10:43  [ТС]
Лучший ответ Сообщение было отмечено как решение

Решение

объяснение
Всё растёт из того, что стандарт Си++ требует того, чтобы 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
Заблокирован
18.11.2011, 06:16
Что-то уж очень противоречивое.
А как все это согласуется с тем, что любой объект в программе может быть определен только один раз.
Здесь явно это правило нарушено.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
22.11.2011, 13:38  [ТС]
Цитата Сообщение от thick_int Посмотреть сообщение
Что-то уж очень противоречивое.
А как все это согласуется с тем, что любой объект в программе может быть определен только один раз.
Здесь явно это правило нарушено.
Объект определён ровно один раз. А два раза определён метод. Если ты два раза напишешь функцию на Си, то у тебя поломается на линковке. А здесь исходник содержит ошибку, но на линковке ошибка не проявилась. Так вот устроен язык Си++, что некоторые из реалиаций языка оказываются ненадёжными в этом плане. Потому что придумать язык мало, надо ещё и понимать, как будет работать компилятор с него и какие при этом могут оказаться подводные камни
0
Заблокирован
22.11.2011, 18:22
Ну уж не знаю, каким Вы компилятором пользуетесь, но я все таки не поленился перекопировал код Вашей так называемой ошибки и вот, что выдает 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.ob j

Ошибка 2 error LNK1169: обнаружен многократно определенный символ - один или более c:\users\...\documents\visual studio 2010\Projects\ErrProj\Debug\ErrProj.exe 1

Так что никакаяя это не трудноуловимая ошибка, а сечется компилятором влегкую.
0
Эксперт С++
5058 / 3118 / 271
Регистрация: 11.11.2009
Сообщений: 7,044
22.11.2011, 19:10
thick_int, вы вообще читаете то, что вам пишут? Я вам помогу:
1
Цитата Сообщение от Evg Посмотреть сообщение
Так вот устроен язык Си++, что некоторые из реалиаций языка оказываются ненадёжными в этом плане
2 GOTO 1
0
Заблокирован
22.11.2011, 19:20
Ну хорошо, Вы уж извините великодушно.
Но все же ради интереса укажите тот ущербный компилятор, который такую лажу не просекает.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
22.11.2011, 20:47  [ТС]
Цитата Сообщение от thick_int Посмотреть сообщение
Но все же ради интереса укажите тот ущербный компилятор, который такую лажу не просекает
Ты вообще читаешь, что в теме пишут?
0
Заблокирован
22.11.2011, 23:54
Да Вы знаете, я так всего то с C++ знаком где-то месяц.
Конечно, еще разбираюсь слабо.
Вы уж так строго не судите новичка.

А что в теме написано, я вот так это и понял, как пишу.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
23.11.2011, 10:43  [ТС]
Пока сентенция сводится к тому, что виндузовые компиляторы ругаются на линковке, а юниксовые - нет. Потому что там и там используются разный формат исполняемого файла, и под виндой, где используется более ущербный формат, не проходят такие финты ушами, которые возможны под юниксом.

Ну и так, для общего сведения. "g++" - это имя компилятора
1
556 / 510 / 25
Регистрация: 23.07.2009
Сообщений: 2,359
Записей в блоге: 1
28.11.2011, 01:16
Цитата Сообщение от Evg Посмотреть сообщение
Пока сентенция сводится к тому, что виндузовые компиляторы ругаются на линковке, а юниксовые - нет. Потому что там и там используются разный формат исполняемого файла, и под виндой, где используется более ущербный формат, не проходят такие финты ушами, которые возможны под юниксом.
подробнее изложи, в чем бОльшая ущербность формата. проиллюстрируй на примере этого случая. это интересно.

пока мне кажется все это раздражением при попытке завинтить шуруп с прямым шлицом крестообразной отверткой. формат то ли отвертки, то ли шурупа - определенно ущербный.

об обобщении "виндузовые компиляторы". недавно было решено старый проект, сделанный под nt vs6 (mfc) развивать дальше ("ведь он уже есть, и успешно работает", почему не использовать оттуда куски, такой франкенштейн создать, и к нему осовремененного добавить, и будет хорошо). на то, чтобы сделать его компилируемым под vs2010, двое пахали одну неделю. потом еще столько же ушло на то, чтобы оно снова заработало. и бой продолжается. постепенно отрезаются омертвевшие части, заменяются новыми. затраты уже, по-моему, превысили затраты на новую разработку. а "всего лишь другой компилятор". и тоже виндоузовый.
0
Evg
Эксперт CАвтор FAQ
 Аватар для Evg
21281 / 8305 / 637
Регистрация: 30.03.2009
Сообщений: 22,660
Записей в блоге: 30
28.11.2011, 11:03  [ТС]
Цитата Сообщение от novi4ok Посмотреть сообщение
подробнее изложи, в чем бОльшая ущербность формата. проиллюстрируй на примере этого случая. это интересно
Это был всего лишь пас назад

Цитата Сообщение от thick_int Посмотреть сообщение
Но все же ради интереса укажите тот ущербный компилятор, который такую лажу не просекает
Добавлено через 4 минуты
Цитата Сообщение от novi4ok Посмотреть сообщение
а "всего лишь другой компилятор". и тоже виндоузовый
Не поверишь, но в линуксе будет то же самое. И дело не только в компиляторе, но и в библиотеках и в интерфейсах операционной системы, и в изменившихся стандартах языка. То бишь на современной операционке скомпилять большую программу 10 летней давности (особенно если на Си++ написано)

Цитата Сообщение от novi4ok Посмотреть сообщение
об обобщении "виндузовые компиляторы"
Это не обобщение, а эмпирическая сентенция на текущий момент. По результату того, где данный пример запускался. И дело не в компиляторе, а в том, как компилятор использует возможности бинарного формата, используемого в винде и в линухе
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
inter-admin
Эксперт
29715 / 6470 / 2152
Регистрация: 06.03.2009
Сообщений: 28,500
Блог
28.11.2011, 11:03
Помогаю со студенческими работами здесь

Объясните разницу во времени исполнения кода
Доброго времени суток. Ниже привожу 2 программы, которые отличаются лишь способом получения степени. 1 программа - через цикл for: ...

Результат исполнения функции
Результат исполнения функции D=POS('T', 'АЭРОПОРТ');

Найти результат исполнения кода
Пусть объявлена функция Number.prototype.toWord(), которая возвращает число прописью, например: (2015).toWord() // две тысячи...

Как в C++ получить результат исполнения внешней команды
Вообщем я пишу простейший код: #include &lt;stdlib.h&gt; #include &lt;iostream&gt; using namespace std; int main () { ...

В каком регистре будет находиться результат исполнения оператора add ax, bx
в каком регистре будет находиться результат исполнения оператора add ax, bx


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Новые блоги и статьи
Знаешь почему 90% людей редко бывают счастливыми?
kumehtar 14.04.2026
Потому что они ждут. Ждут выходных, ждут отпуска, ждут удачного момента. . . а удачный момент так и не приходит.
Фиксация колонок в отчете СКД
Maks 14.04.2026
Фиксация колонок в СКД отчета типа Таблица. Задача: зафиксировать три левых колонки в отчете. Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) / / . . .
Настройки VS Code
Loafer 13.04.2026
{ "cmake. configureOnOpen": false, "diffEditor. ignoreTrimWhitespace": true, "editor. guides. bracketPairs": "active", "extensions. ignoreRecommendations": true, . . .
Оптимизация кода на разграничение прав доступа к элементам формы
Maks 13.04.2026
Алгоритм из решения ниже реализован на нетиповом документе, разработанного в конфигурации КА2. Задачи, как таковой, поставлено не было, проделанное ниже исключительно моя инициатива. Было так:. . .
Контроль заполнения и очистка дат в зависимости от значения перечислений
Maks 12.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: реализовать контроль корректности заполнения дат назначения. . .
Архитектура слоя интернета для сервера-слоя.
Hrethgir 11.04.2026
В продолжение https:/ / www. cyberforum. ru/ blogs/ 223907/ 10860. html Знаешь что я подумал? Раз мы все источники пишем в голове ветки, то ничего не мешает добавить в голову такой источник, который сам. . .
Подстановка значения реквизита справочника в табличную часть документа
Maks 10.04.2026
Алгоритм из решения ниже реализован на примере нетипового документа "ПланированиеПерсонала", разработанного в конфигурации КА2. Задача: при выборе сотрудника (справочник Сотрудники) в ТЧ документа. . .
Очистка реквизитов документа при копировании
Maks 09.04.2026
Алгоритм из решения ниже применим как для типовых, так и для нетиповых документов на самых различных конфигурациях. Задача: при копировании документа очищать определенные реквизиты и табличную. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru