Взятие адреса временного (составного литерала) параметра в C

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

Законно ли взять адрес временной конструкции в списке параметров вызова функции в C99?

Например, что-то вроде init_list или init_desig_init следующим образом:

typedef struct {
  int x;
  int y;
} point_t;

int manhattan(point_t *p) {
  return p->x + p->y;
}

int init_list() {
  return manhattan(&(point_t){1, 2});
}

int init_desig_init() {
  return manhattan(&(point_t){.x = 1});
}

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


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

1 На самом деле я должен назвать это "большой кросс-платформенной тройкой" из уважения к MSVC, но на самом деле я просто имею в виду "компиляторы C, которые поддерживает godbolt".


person BeeOnRope    schedule 29.01.2017    source источник
comment
Ответ, который вы получили, хорош, но есть небольшая ошибка, о которой стоит помнить, когда вы начнете более широко использовать составные литералы: stackoverflow.com/questions/34880638/   -  person Art    schedule 01.02.2017
comment
@Art - очень хороший момент. Как будто было недостаточно пытаться запомнить разные правила жизни для составных литералов в C по сравнению с временными литералами в C++...   -  person BeeOnRope    schedule 01.02.2017


Ответы (1)


(point_t){1, 2} не является "временным". Это составной литерал. (Одна и та же последовательность токенов в C++ имеет другое значение, эти два языка не следует путать друг с другом).

Составной литерал — это lvalue, поэтому с ним можно использовать унарный оператор &. Срок хранения указан в C11 6.5.2.5/5:

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

Так что этот код правильный, и составной литерал продолжает существовать до конца функции, в которой он был объявлен.

person M.M    schedule 30.01.2017
comment
Спасибо. Мое использование временного также частично объясняет, почему мне было так трудно искать подробности об этом. Для дополнительной справки, вот документ gcc по составным литералам . - person BeeOnRope; 30.01.2017