LINUX.ORG.RU

non-static data member initializers варнинги

 , ,


0

1

Пишу небольшой проект на Qt. Это мой первый проект на Qt/C++ сложнее Хэллоуворлда, поэтому еще не совсем разобрался. При сборке QtCreator выдает дикое количество одинаковых варнингов (где-то около ста). Вот пример одно из них:

предупреждение: non-static data member initializers only available 
with -std=c++11 or -std=gnu++11 [enabled by default]
     const QUrl apiTestServerUrl = QUrl("https://some.url.com/");
                                                               ^

Я конечно понял что так можно делать только начиная с с++11, но поддрежка этого стандарта включена по дефолту, поэтому всё работает. Теперь вопрос, как избавиться от этих варнингов?(ну кроме того, что писать не используя с++11), ну то есть, как выключить вывод именно этого типа варнингов? Из-за них можно пропустить действительно нужный варнинг.

Deleted

Дык игнорируй, это просто варнинг о том, что в определённых случаях (когда поддержки c++11 нет) программа работать не будет.

Хотя, что-то меня в этом коде напрягает...

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

Ну я их и игнорирую, но много, и в них теряются другие варнинги

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

Хэдэр этого класса полностью:

#ifndef APICONNECTOR_H
#define APICONNECTOR_H
class ApiConnector : public QObject
{
    Q_OBJECT
public:
    explicit ApiConnector(QObject *parent = 0);

private:
    QNetworkAccessManager *netwAccessManager;
    QByteArray data;
    const QUrl apiTestServerUrl = QUrl("https://some.url.com");

    QUrl constructXmlUrl(QString path, bool isTestServer, QString query);

signals:
    void newXml(QString&, QString&);

public slots:
    void getNewXml(QString path, bool isTestServer, QString query);
    void onFinish(QNetworkReply *reply);
};

#endif // APICONNECTOR_H

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

const QUrl apiTestServerUrl = QUrl("https://some.url.com");

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

public:
    ApiConnector():
            apiTestServerUrl("https://some.url.com") {
    };

private:
    QUrl apiTestServerUrl;
x0r ★★★★★
()
Ответ на: комментарий от Deleted

Товарищ выше посоветовал, поддерживаю его.

false ★★★★★
()

или добавь CONFIG += c++11, или перепиши по-старинке в конструкторе перед телом, как x0r советует.

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

просто дожили, в компиляторах поддержка С++11 уже по-умолчанию включен

а почему она не должна быть включена?

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

сделал const QUrl apiTestServerUrl("https://some.url.com/");

ошибка: expected identifier before string constant
     const QUrl apiTestServerUrl("https://some.url.com/");
                                 ^
ошибка: expected ',' or '...' before string constant

Deleted
()

Это в классе так? Можно конечно, и -std=c++11 включить, но можно и объявить указателем и в конструкторе уже создавать объект.

a1batross ★★★★★
()
Последнее исправление: a1batross (всего исправлений: 1)
Ответ на: комментарий от Adonai

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

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

надеюсь в C++14 это выпилят. ужасно же.
x0r ★★★★ (27.04.2014 19:03:33) его код лучше не читать

И чтоб я делал без этой супер лор-фичи?..

Не делай инициализацию в хеадере, да возможность есть, но этим тебе оторвет шары в перспективе(что-то вроде исключений).

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

MyClass::MyClass() :
  apiTestServerUrl("EnlargeYourPony.com")
{
  // or
  apiTestServerUrl = QUrl("EnlargeYourPony.com");
}


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

надеюсь в C++14 это выпилят. ужасно же.

очень даже удобно, не надо всякие флаги, например, в конструкторах инициализировать, или указатели в nullptr

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

Изменяя значения одной переменной в итоге повлечет пере-сборку всех модулей, которые включают этот заголовок,

как и при любом изменении в хедере, предлагаешь их не редактировать?

Да и зачем тратить свое время на ожидание?

затем, что так банально надежнее - одно очевидное место инициализации, вместо возможных нескольких конструкторов или функции для инициализации

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

См. выше, хреново вообще в заголовке кишки выставлять

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

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

Да, я предлагаю их не редактировать, ибо заголовок - интерфейс и там кишек быть не должно. Кстати и в самой Qt так делают, выводят только public, protected методы, а все свойства и protected методы прячут в самом cpp. Для не либы, это overkill. Значения, которым будут изменять значение там не место.

По второму пункту - :D

Конструктор будет всегда(ну почти всегда), т.е. теперь инициализация будет и в *.h и в *.cpp. Иными словами ты доказал, что ты неправ :)

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

Темплейты - другое дело, там иного не дано.

https://qt.gitorious.org/qt/richs-qtbase/source/13b83d896de8b00d6a373c97917ce...

Обрати внимание, что все inline методы вызывают методы интерфейса. И то что там нет никаких свойств в классе, кроме QWidgetData *data, где и лежат все данные. Почти любое изменение в заголовки и бинарная совместимость просрана, что для либ очень не желательно.

frozenix ★★★
()

Сколько людей отписалось, а главного не сказали, наоборот только дезинформировали друг друга: [enabled by default] относиться к предупреждению, а не к поддержке C++11.

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

Кстати и в самой Qt так делают, выводят только public, protected методы, а все свойства и protected методы прячут в самом cpp

открой qstring.h, например, и посмотри

Конструктор будет всегда(ну почти всегда), т.е. теперь инициализация будет и в *.h и в *.cpp. Иными словами ты доказал, что ты неправ :)

инициализация всегда была «и в *.h и в *.cpp», просто неявная, когда использовался конструктор по-умолчанию, например

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

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

а ты уверен, что инициализация полей в хедере ее поломает? ;)

wota ★★
()
Ответ на: комментарий от wota
// qstring.h
Data *d;

Я там что-то пропустил?

Ну а теперь ты предлагаешь делать инициализацию в двух разных файлах под предлогом, что лучше делать все в одном месте.

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

и? скоро этого предупреждения не будет. VS вообще молча сожрет, ибо там c++11 дефолтом идет и в gcc он дефолтом будет.

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

Я там что-то пропустил?

QLatin1String, например, сразу в начале, QStaticStringData, или вот это, например:

struct Q_CORE_EXPORT QArrayData
{
    QtPrivate::RefCount ref;
    int size;
    uint alloc : 31;
    uint capacityReserved : 1;

    qptrdiff offset; // in bytes from beginning of header

    void *data()
    {
        Q_ASSERT(size == 0
                || offset < 0 || size_t(offset) >= sizeof(QArrayData));
        return reinterpret_cast<char *>(this) + offset;
    }

    const void *data() const
    {
        Q_ASSERT(size == 0
                || offset < 0 || size_t(offset) >= sizeof(QArrayData));
        return reinterpret_cast<const char *>(this) + offset;
    }

    // This refers to array data mutability, not "header data" represented by
    // data members in QArrayData. Shared data (array and header) must still
    // follow COW principles.
    bool isMutable() const
    {
        return alloc != 0;
    }

    enum AllocationOption {
        CapacityReserved    = 0x1,
        Unsharable          = 0x2,
        RawData             = 0x4,
        Grow                = 0x8,

        Default = 0
    };

    Q_DECLARE_FLAGS(AllocationOptions, AllocationOption)

    size_t detachCapacity(size_t newSize) const
    {
        if (capacityReserved && newSize < alloc)
            return alloc;
        return newSize;
    }

    AllocationOptions detachFlags() const
    {
        AllocationOptions result;
        if (!ref.isSharable())
            result |= Unsharable;
        if (capacityReserved)
            result |= CapacityReserved;
        return result;
    }

    AllocationOptions cloneFlags() const
    {
        AllocationOptions result;
        if (capacityReserved)
            result |= CapacityReserved;
        return result;
    }

    static QArrayData *allocate(size_t objectSize, size_t alignment,
            size_t capacity, AllocationOptions options = Default)
        Q_REQUIRED_RESULT;
    static void deallocate(QArrayData *data, size_t objectSize,
            size_t alignment);

    static const QArrayData shared_null[2];
    static QArrayData *sharedNull() { return const_cast<QArrayData*>(shared_null); }
};

Ну а теперь ты предлагаешь делать инициализацию в двух разных файлах под предлогом, что лучше делать все в одном месте.

инициализация в хедере, изменение - в конструкторе или методах

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

мне не оче нравится смешивание декларации аттрибутов и их инициализация.

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

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

Исключение из правила только подтверждает правило?

Это счетчик ссылок, и далеко не обычный класс. Смотри тот же QString.

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

Бред вымочил ты, сказав, что код работать не должен и что это не стандарт.

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

Да, а вот ты бы сходил и проверил.

значит ты ошибся, опять:

$ cat 1.h 1.cpp 3.h 3.cpp main1.cpp main3.cpp 
struct A
{
        A();

        int dummy( void ) const { return 0; }
        int value( void ) const { return a; }
        int a = 5;
};
#include "1.h"

A::A()
{
}
struct A
{
        A();

        int dummy( void ) const { return 0; }
        int value( void ) const { return a; }
        int a;
};
#include "3.h"

A::A()
:
   a( 5 )
{
}
#include "1.h"
#include <cstdio>

int main()
{
        A a;
        printf( "%d\n", a.value() );
}
#include "3.h"
#include <cstdio>

int main()
{
        A a;
        printf( "%d\n", a.value() );
}
~$ g++ -std=c++11 -shared 1.cpp -o 1.so
~$ g++ -shared 3.cpp -o 3.so
~$ g++ -std=c++11 main1.cpp ./3.so
~$ ./a.out 
5
~$ g++ main3.cpp ./1.so
~$ ./a.out 
5
wota ★★
()
Ответ на: комментарий от frozenix

Исключение из правила только подтверждает правило?

«единого универсального правила тут нет» (c) wota

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

Hacks, sweet hacks.

Теперь сделай это любой системой сборки или попробуй взять какой-то не тривиальный тип.

Заголовок с struct A изменился? Да. Теперь нужно пересобрать все файлы, которые его включают.

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

Hacks, sweet hacks.
Теперь сделай это любой системой сборки или попробуй взять какой-то не тривиальный тип.

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

Заголовок с struct A изменился? Да. Теперь нужно пересобрать все файлы, которые его включают.

офигеть, а после изменения комментариев или форматирования ты тоже все пересобираешь? повторюсь - данное изменение ничего не изменит в плане совместимости

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

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

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

По умолчанию включён gnu++98, который разрешает такие конструкции, но с предупреждениями. Я бы не назвал это поддержкой 11-го стандарта по умолчанию, скорее мягкое неявное поведение при настройках из коробки.

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

Во-первых, не факт, что скоро. Про будущие новые настройки по умолчанию в man-странице написано для C99 (не C11), но не для C++11.

Во-вторых, как это относиться к тому, что я написал? Я указывал на заблуждение и то, что обсуждение привело к неверным выводам, а не говорил про стандарт языка по умолчанию.

P.S. В VS С++11 не является умолчанием, он там является единственным вариантом, так как возможность выбора стандарта отсутствует в принципе. Максимум, что можно, так это отключить расширения языка. Так что сравнение не очень удачное.

xaizek ★★★★★
()

кстати, смотрел ОП в полглаза, 2ТС, лучше писать:

const QUrl apiTestServerUrl { "https://some.url.com/" };

меньше кода будет и читабельнее

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

См. выше, хреново вообще в заголовке кишки выставлять. Да и вообще разделение .h & .cpp довольно паршивая вещь.

По моему, ты сам себе противоречишь. Не было бы разделения - все кишки точно были бы видны, нет?

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