LINUX.ORG.RU
ФорумTalks

Code Less, Create More


0

0

Те, кто интересуется Qt наверняка посещают главную страницу Нокии http://qt.nokia.com. Интересно сколько из них всматривались в иконку «Developers», вот в эту самую: http://qt.nokia.com/portal_css/Qt%20Theme%202010/developer_icon.png.

На этом клапте 2x3 см умудрились втулить:

1. Негативную условную компиляцию: #if !defined() вместо #ifdef

2. Сам макрос переключения платформ #if !defined(Q_OS_), что идёт врознь с идеями кроссплатформенного программирования на Qt.

3. Отсутствие const-квалификатора перед app:

QString app = QLatin1String( "a" );
#if !defined(Q_OS_...)
    app += QLatin1String( "b" );
#else
    app += QLatin1String( "c" );
#endif

Вместо:

const QString app = QString::fromLatin1( "a" ) +
#if !defined(Q_OS_...)
    QLatin1String( "b" );
#else
    QLatin1String( "c" );
#endif

Хочется взять этот самый молоток и размельчить сию могильнуюю плиту, а авторам выдать книжку Андрея Александреску «Стандарты программирования C++».

И да, кто-нибудь знает, что это на иконке за пуля и белые комочки?

★★★★★

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

Yareg ★★★
()

Это, кстати, вполне может быть куском кода куте, можешь поискать полную версию.

Yareg ★★★
()

1) Ничего плохого в этом нет. 2) Тут уже отметились люди, сказавшие, что ЭТО и есть основа кросс-платформенности, ибо API, в том числе и системные везде разные. 3) Сомнительно, ибо зависит от контекста.

irq
()

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

2) Troll less, lurk more :)

annulen ★★★★★
()

это просто иконка... понимаете?

najar
()

В 1,3 ничего страшного нет, а вот без второго - как программа еще будет отвечать принципу «write once, compile evwrywhere» ?

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

Попробую обьяснить.

1. Негативную условную компиляцию: #if !defined() вместо #ifdef

1) Ничего плохого в этом нет.

Негативные макросы вводят в заблуждение, к примеру #if !defined(Q_OS_WIN) - это что за ОС такая не-Windows? OSX, Linux, Symbian? Получается заранее нельзя предсказать, будет ли код выполняться на любой из этих не-Windows платформ, а скорее всего программа вообще пишется только для одной из них и догадаться для какой именно можно только с помощью магии. К примеру заглянув, что под макросом прячется app += ".so" - ага, значит автор под не-Windows подразумевал Linux. Портировать на третью платформу код с негативными макросами - одна головная боль. Хотя бы потому, что они не дают поставить исключение. Сравните:

#if !defined(Q_OS_WIN)
    app += ".so";
#else
    app += ".dll";
#endif

и

#if defined(Q_OS_WIN)
    app += ".dll";
#elif defined(Q_OS_LINUX)
    app += ".so";
#else
#error "Implement this for your OS"
#endif

В первом случае код соберётся и даже не пикнет, что он будет работать некорректно. В случае с позитивными макросами компиллятор сразу даст по рукам.

2) Тут уже отметились люди, сказавшие, что ЭТО и есть основа кросс-платформенности, ибо API, в том числе и системные везде разные.

Да, вот только Qt подразумевает, что большинство платформозависимого кода спрятано в нём самом, а программист пользуется именно кроссплатформенным API. Как-то вяло такой макрос вписывается в рекламную иконку.

3) Сомнительно, ибо зависит от контекста.

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

inline QString calculateMyString()
{
    QString app = ...;
    if ( someCondition )
        app += ...;
    else
        app += ...;
    return app;
}
...
const QString app = calculateMyString();
Dendy ★★★★★
() автор топика
Ответ на: комментарий от Dendy

1) Я не спорю, зачастую удобнее использовать ваш вариант, но что делать, если мне нужно что-то вроде «все, кроме»?

Или, например, ставшая уже стандартом де-факто структура *.h файла, я имею в виду это

#if !defined NAME_H
#define NAME_H
...
#endif // NAME_H

Я полагаю, что предпочтения программиста в выборе позитивной или негативной версии, зависят от его образа мышления. В любом случае оба варианта имеют право на жизнь.

2) А почему вы думаете, что эти несколько строк гипотетически не могут быть в самом кьют?

3) Про inline печи не было, вы говорили про const.

irq
()

Зачем там могильная плита? )

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

Надеюсь автор услышит мой ответ в «Уведомлениях» (-:

1) Я не спорю, зачастую удобнее использовать ваш вариант, но что делать, если мне нужно что-то вроде «все, кроме»?


Приведите пример, мне кажется эти случаи не выдержат критики.

Или, например, ставшая уже стандартом де-факто структура *.h файла, я имею в виду это


Во-первых, это хак, которым продолжают пользоваться только дремучие ретрограды, не слышавшие про #pragma once. Во-вторых, в данном случае отсутвует условная компиляция для платформы, другими словами в этом примере условие самодостаточно, оно отвечает на изначальный вопрос - был ли уже включён файл. Тогда как в случае выбора платформы #if !defined(Q_OS_WIN) - условие не отвечает изначальный на вопрос. Вобщем - приведите пример, а я попробую обьяснить как стоило бы его переделать.

2) А почему вы думаете, что эти несколько строк гипотетически не могут быть в самом кьют?


Да скорее так оно и есть (-: Только кому интересны внутренности самого Qt...

3) Про inline печи не было, вы говорили про const.


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

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