вызов функции в инициализации структуры - PullRequest
0 голосов
/ 24 ноября 2018

Рассмотрим следующий фрагмент:

struct my_struct {
     int a;
     int b;
     int c;
};


void my_func(unsigned long x)
{
    struct my_struct m[] = {
         { 0, 1, 2 },
         { 11, 22, htonl(x) },
         { 0x1, 0xa, 0xbb }
    };
    ...
}

Законно / переносимо ли вызывать функцию внутри блока инициализации структуры?

Ответы [ 2 ]

0 голосов
/ 24 ноября 2018

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

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

int foo()
{
  static int a;
  return ++a;
}

int main()
{
  struct { int x, y; } s = { foo(), foo() };
  /* Can be `{ 1, 2 }` or `{ 2, 1 }`... */
}

Что касается переносимости, можно заметить, что C89 / 90 сделалне разрешать этого (формально в C89 / 90 все {} -замкнутые инициализаторы должны быть константными выражениями, даже для автоматических объектов), но большинство популярных компиляторов C89 / 90 поддерживали это независимо.

0 голосов
/ 24 ноября 2018

Является ли законным / переносимым вызывать функцию внутри блока инициализации структуры?

Инициализация (§6.7.8 / 1)

[...]

|     initializer-list:
|             designationopt initializer
|             initializer-list , designationopt initializer

~> списки инициализаторов состоят из инициализаторов

Инициализация (§6.7.8/4)

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

~> Инициализаторы состоят из выражений.(постоянное выражение для объектов со статической продолжительностью хранения)

Выражения (§6.5 / 1) :

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

~> Вызов функциивыражение.

...