LINUX.ORG.RU

Проверка на знание документации

 ,


1

2

Добрый день, мои дорогие любители указателей и множественного наследования.

Каждый пользователь Qt очень часто в своей жизни сталкивается с подобным кодом:

int main( int argc, char** argv)
{
    QApplication app( argc, argv);
    int result = app.exec();
    return result;
}

Этот тривиальный пример стал настолько близким и родным каждому, кто пишет код на C++/Qt, что вопросов по его работе не возникает ни у кого. Но давайте попробуем окунуться немного глубже и рассмотрим вот такой пример:

QApplication* createApplication( int argc, char** argv)
{
    QApplication* result = new QApplication( argc, argv);
    return result;
}

int main( int argc, char** argv)
{
    QApplication* app = createApplication( argc, argv);
    int result = app->exec();
    delete app;
    return result;
}

Прошу вас, не пытайтесь повторить этот трюк в реальных приложениях. В особенности, если от них зависит жизнь и здоровье людей (хотя бы разработчиков), т.к. этот код приводит к undefined behavivor.

Первый, кто сможет объяснить почему, получит в награду картонную медаль и общественное признание, как человек, глубоко знающий работу любимой многими библиотеки.

Итак, ждем нашего победителя.

---

Наш победитель: slovazap

Осторожно, ниже в треде есть ответы. Если вы хотите сами найти решение - не читайте тред до конца.

★★★★★

Последнее исправление: trex6 (всего исправлений: 2)
Ответ на: комментарий от trex6

Если что-то принимает ссылку или указатель на объект, это что-то *может* ожидать длительного существования объекта. Проблема здесь только в голове, сам давно встречал такое, поматерился и запомнил на всю жизнь. Передал указатель — будь добр обеспечить excessive lifetime в соответствии с традициями платформы. От изменения способа передачи сразу возникает неприятное ощущение, но документировать такие места надо, согласен.

arturpub ★★
()
Ответ на: комментарий от arturpub

Ну и таки да, даже не имей Qt такой особенности, легко можно нарваться на atexit или выйти за argv — этого никто не отменял.

arturpub ★★
()
Ответ на: комментарий от trex6

В приложении - несколько потоков, куча классов.

Сочувствую :/

arturpub ★★
()
Ответ на: комментарий от invy

В документации написано - результат неопределен. А значит, что он может быть любой. rand() бы вас больше устроил?

trex6 ★★★★★
() автор топика

Наш победитель: slovazap

Реквестрирую пруф высланной картонной медали.
//эх, надо было ботать qt, а не совокупляться с gtkmm...

comp00 ★★★★
()
Ответ на: комментарий от arturpub

Документация. Если бы меня внятно и громко предупредили, что с argc будет происходить, я бы в эту ловушку не попал.

Думаю, тут дело в том, что с QApplicatin мы знакомимся очень рано, когда еще нет времени подробно читать документацию на каждый метод класса. Потом свыаемся с тем, что он простой как палка и работает на 5+. И лишь вот в такие моменты понимаешь, что документацию надо читать на весь класс. Как минимум на все методы, которые используешь в приложении. Читать внимательно, вдумчиво, откладывая в мозг такие вот тонкости.

trex6 ★★★★★
() автор топика
Ответ на: комментарий от comp00

Медаль будет вручена герою на следующей лор-сходке города ДС2 или на любой дрогой сходке в этом городе, на которую герой прибудет за медалью.

trex6 ★★★★★
() автор топика
Ответ на: комментарий от trex6

Бесполезно, проверял. Когда прямо пишешь, все всплывает, а когда «рефакторишь», куча связей теряется, потому что контекста в голове нет. Тут надежда только на встроенную чуйку и скилл в отладчике.

arturpub ★★
()
Ответ на: комментарий от BlackRaven86

А смысл? Бинарная совсместимость решает. К тому же с этой особенностью, как я понял, крутые дядьки уже вполне знакомы, а остальным еще предстоит.

Хотел поругаться в #qt, но сил душевных не было. Может быть в понедельник найдутся, там ведь на английском надо общаться...

trex6 ★★★★★
() автор топика
Ответ на: комментарий от trex6

А разве нельзя не ломать ее? Например, хранить значение, а не ссылку. Интерфейс не поменяется же. Да и в документации на крайний случай могут отметить.

BlackRaven86
()

Так это... Желаю хорошего статического анализатора кода/нормального компилятора нам, сишнекам

nerdogeek
()
Ответ на: комментарий от trex6

А смысл? Бинарная совсместимость решает.

дык, если оно в d-pointer'e, то бинарная совместимость пропасть не должна

Stil ★★★★★
()
Ответ на: комментарий от gag

Пробовал на struct: отличие же только в приватности по умолчанию. Да, оказывается, что если объявить ссылку приватной и обязательно добавить конструктор с её инициализацией, то можно.

Ничего не понял. Почему обязательно приватной?

struct A
{
    int &a_;
    A(int& a) : a_(a) {}
};

int main() {
    int b = 123;
    A a(b);
}

Ключевой момент в том, что ссылка должна быть инициализирована, а квалификаторы доступа тут не при чем.

DELIRIUM ☆☆☆☆☆
()
Последнее исправление: DELIRIUM (всего исправлений: 1)
Ответ на: комментарий от BlackRaven86

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

Формально они все такие в белом и на коне, а реально...

trex6 ★★★★★
() автор топика
Ответ на: комментарий от trex6

Если разобраться, у них есть причины так делать:

Argc and argv are changed if QApplication recognizes (and processes) passed arguments. For example: "-style=windows" - argument is recognized and removed from the argv-list. Unrecognized arguments can be accessed by using: QCoreApplication::arguments().

BlackRaven86
()
Ответ на: комментарий от BlackRaven86

Зачем они это делают - тоже очень большой вопрос, но в любом случае даже если они что-то там поменяли - это еще не повод хранить ссылку. Могли бы хранить измененное значение.

trex6 ★★★★★
() автор топика

Кресты такие кресты.
Чтобы увидеть потенциальную ошибку в простой на первый взгляд строке кода нужно либо курить документацию (если она есть и верна), либо подробно раскуривать код (определения, перегрузки операторов, наследования.......).

Tayler ★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.