Перейти к содержанию
    

Плавный переход C -> C++ под МК

8 minutes ago, Arlleex said:

Вопрос следующий: с какой (неведомой мне пока что на данном этапе) целью комитет избавился от назначенной инициализации, как это было в C99?

Откуда такая информация? Можно ссылку? Я такого не видел.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 минуту назад, one_eight_seven сказал:

Откуда такая информация? Можно ссылку? Я такого не видел.

Ну, в С99 можно было пользоваться назначенной инициализацией, а в C++ уже нельзя.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

5 minutes ago, Arlleex said:

Ну, в С99 можно было пользоваться назначенной инициализацией, а в C++ уже нельзя.

https://en.cppreference.com/w/cpp/language/aggregate_initialization

P.S.

$ g++ tst2.cpp 
$ ./a.out 
$ g++ --version
g++ (GCC) 11.1.1 20210428 (Red Hat 11.1.1-1)
Copyright (C) 2021 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

[avi@dev ~]$ cat tst2.cpp 
struct Person
{
    int height;
    int weight;
    int age;
};

int main()
{
    struct Person p { .age = 18 };
    return 0;
}

как видите, добавил одно лишь слово 'struct' при объявлении Person p, и всё компилируется и работает.

Изменено пользователем one_eight_seven

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

typedef struct
{
  u32          cid, tskpsp[EDS_MAXTSK_QNT];
  volatile u32 tmr, tsktmr[EDS_USRTSK_QNT];
}sEDS;

static u32 stack[EDS_MNGSTK_SIZE];

sEDS EDS = {.tskpsp[0] = (u32)&stack[EDS_MNGSTK_SIZE]};


И как такое провернуть в C++? Keil выдает предупреждения

Цитата

sources/services/eds/eds.cpp(10): warning: nested designators are a C99 extension [-Wc99-designator]
sources/services/eds/eds.cpp(10): warning: array designators are a C99 extension [-Wc99-designator]


О блин, а вот так можно (вроде не ругается)

typedef struct sEDS
{
  u32          cid, tskpsp[EDS_MAXTSK_QNT];
  volatile u32 tmr, tsktmr[EDS_USRTSK_QNT];
  public: sEDS(u32 i) : tskpsp{[0] = i} {}
}sEDS;

static u32 stack[EDS_MNGSTK_SIZE];

sEDS EDS((u32)&stack[EDS_MNGSTK_SIZE]);


Ну и намудрили же там с этими инициализациями...:wacko2:

P.S. А, нет, мой способ тоже не работает - warning: array designators are a C99 extension [-Wc99-designator].

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

static const auto EDS_MAXTSK_QNT = 4;
static const auto EDS_USRTSK_QNT = 7;
static const auto EDS_MNGSTK_SIZE = 10;

typedef struct
{
  uint32_t          cid, tskpsp[EDS_MAXTSK_QNT];
  volatile uint32_t tmr, tsktmr[EDS_USRTSK_QNT];
}sEDS;

static uint32_t stack[EDS_MNGSTK_SIZE];

sEDS EDS = {.tskpsp[0] = (uint32_t)&stack[EDS_MNGSTK_SIZE]};

Компилируется в IAR. В листинг уже не смотрел, ибо, думаю, оптимизатор всё это выкинул. Но ошибок и предупреждений не было.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

1 час назад, haker_fox сказал:

Компилируется в IAR...

А у меня ж в примере выше та же нотация объявления EDS с инициализацией. Warning есть...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Just now, Arlleex said:

Warning есть...

Наверное, особенности одного или обоих компиляторов. У меня IAR 8.40.1, C++17.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А, может, они уже там что-то в 17 версии передумали по поводу инициализации. Насколько мне удалось узнать, инициализация - самая больная тема C++.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Здесь можно поиграться с разными компиляторами. С clang у меня появились ваши предупреждения, а gcc вообще выдал ошибку(( Видимо, каждый компилятор сам разруливает ситуацию...

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У меня вот еще вопрос следующий.

Чем инициализация членов класса списком отличается от прямой копирующей инициализации (присваиванием) в конструкторе? Т.е. чем это

struct A
{
  int a, b, c;
  A(int init) : a(init) {}
}A;

отличается от этого

struct A
{
  int a, b, c;
  A(int init) {a = init;}
}A;

, ведь с точки зрения программиста в обоих примерах A.a получает значение до вызова main(), т.е. в процессе инициализации среды выполнения. Но раз есть два синтаксиса, то в чем отличие? Мне только на ум приходят только мысли, что это сделано для инициализации каких-то константных данных класса или ссылок, которые явно операцией присваивания в конструкторе "не задать". Так ли это?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

9 minutes ago, Arlleex said:

каких-то константных данных класса или ссылок

Это так.

9 minutes ago, Arlleex said:

отличается от этого

Во втором случае ещё можно и какой-то код написать, который инициализирует вашу переменную по условию, например.

Также первый случай подходит для инициализации конструктора родительского класса.

class Children : public Parent {
public:
  	Children( int myAge, int parentAge )
    : Parent(parentAge)
    , m_age(myAge) {
      	if(myAge <= 14 )
           printf( "I'm children...(((" );
        else if(myAge <= 18 )
           printf*( "I'm teenager...)" );
        else
           printf("I can fuck any pretty woman)");
    }  
};

P.S. Сорри за мат в принтфах, я обычно не матерюсь, но для поднятия настроения можно)))

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

20 минут назад, Arlleex сказал:

Чем инициализация членов класса списком отличается

Во втором случае у вас сначала происходит инициализация по умолчанию.

Тут подробнее объяснено: https://ru.stackoverflow.com/a/622581

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

17 минут назад, haker_fox сказал:

Сорри за мат в принтфах

:diablo:Есть множество не менее забавных шаблонов для printf. Из времен PC XT и CGA помнится "slap nearest innocent bystander".

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

9 минут назад, Grizzly сказал:

Во втором случае у вас сначала происходит инициализация по умолчанию...

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

27 минут назад, haker_fox сказал:

P.S. Сорри за мат в принтфах...

Помню как один такой "прикол" всплыл у юзеров нашего ПО, после этого не очень хотелось чудить в printf-ах:acute:

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

3 часа назад, Arlleex сказал:

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

В вашем случае. Но вообще членами класса могут быть другие классы, константы, ссылки. Последние две группы можно инициализировать только через список инициализации.

Если же членом является класс, то для него будет вызываться сначала конструктор по умолчанию, а уже потом оператор присваивания, для объекта, который будет сконструирован в теле конструктора вашего класса. Не очень хорошо с точки зрения performance, тем более в emdedded. В случае же списка инициализации будет однократно создан только нужный вам объект. Поэтому хорошим тором является всегда использовать списки инициализации.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

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

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...