2017-01-29 38 views
8

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

Является ли законным принимать адрес временного, построенного в списке параметров вызова функции в 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}); 
} 

Большой три seem to compile it OK, но я не мог на самом деле найти ссылку объясняя, что срок службы временно будет продлен на как минимум через вызов функции.


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

Я бы назвал это «большой кросс-платформенный три» действительно, в знак уважения к MSVC, но на самом деле я просто имею в виду «поддерживающие крепители C-компиляторов».

+1

Ответ вы получили это хорошо, но есть немного Понял, что стоит иметь в виду, когда вы более активно используете сложные литералы: http://stackoverflow.com/questions/34880638/compound-literal-lifetime-and-if-blocks – Art

+0

@Art - очень хорошая точка. Поскольку это, если еще не было достаточно, чтобы вспомнить разные правила жизни для сложных литералов в C по сравнению с временными в C++ ... – BeeOnRope

ответ

7

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

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

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

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

+0

Спасибо. Мое использование «временного» также отчасти объясняет, почему я так тяжело искал подробности об этом. Для дополнительной справки, здесь [gcc doc on _compound literals_] (https://gcc.gnu.org/onlinedocs/gcc/Compound-Literals.html). – BeeOnRope

 Смежные вопросы

  • Нет связанных вопросов^_^