Подтвердить что ты не робот

Что означает & (int) {1} в С++?

Я видел это здесь, и я не знаю, что это значит:

&(int) { 1 }

Я думал, что это было странно, потому что это похоже на недействительный синтаксис. Он отбрасывает область блока (?) Со случайным 1 посередине (без полуколонии) и берет адрес. Не имеет большого смысла для меня. Не могли бы вы, ребята, просветить меня?

Пробовал w/С++ 11, поэтому он компилирует:

auto a = &(int) { 1 };

Но я понятия не имею, что делать с переменной.

4b9b3361

Ответ 1

Насколько я могу судить, это составной литерал, это функция C99, это не стандартный С++, но и gcc и clang поддерживают его как расширение:

ISO C99 поддерживает сложные литералы. Комбинированный литерал выглядит как листинг, содержащий инициализатор. Его значение является объектом типа, указанного в листинге, содержащего элементы, указанные в инициализаторе; это значение lvalue. В качестве расширения GCC поддерживает сложные литералы в режиме C90 и на С++, хотя семантика несколько отличается на С++.

Обычно указанный тип является структурой. Предположим, что struct foo и Структура объявляется как показано:

 struct foo {int a; char b[2];} structure;

Вот пример построения структуры foo с соединением буквальный:

 structure = ((struct foo) {x + y, 'a', 0});

Это эквивалентно написанию следующего:

 {
   struct foo temp = {x + y, 'a', 0};
   struct

В этом случае тип a будет указывать на int. Надеюсь, это был исходный код C, поскольку в документе gcc говорится:

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

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

Это один из тех случаев, когда использование правильных флагов действительно очень помогает, как в gcc, так и в clang, используя - pedantic будет создавать предупреждение и ошибка, например gcc говорит:

warning: ISO C++ forbids compound-literals [-Wpedantic]
 auto a = &(int) { 1 };
                     ^
error: taking address of temporary [-fpermissive]

если мы используем -fpermissive, это gcc, это действительно позволяет компилировать этот код. Я не могу заставить clang создать этот код с любыми флагами в современных версиях, хотя старые версии, похоже, позволяют использовать его -Wno-address-of-temporary. Интересно, может ли gcc использовать это как остаток старого расширения.

Обратите внимание, что вопрос Cryptic struct definition в C имеет довольно интересное (в зависимости от вашего определения интересное) использование сложных литералов.

Предполагая, что раскол верен и этот вопрос является исходным источником, а затем используется в этом коде в пример:

if (setsockopt(server_connection.socket, SOL_SOCKET, SO_REUSEADDR, &(int) { 1 }, sizeof(int)) < 0) {

является допустимым использованием как на C99, так и на С++.

Ответ 2

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

Он берет адрес временной анонимной структуры, содержащей одно анонимное целое число, которое инициализируется с помощью инициализатора, назначенного C99. Причина в том, что setsockopt не хочет целое число, а указатель на него (вернее, указатель на что-то и что-то размер).

Другими словами, очень классный взлом для предоставления целочисленного аргумента (без явной переменной temp) функции, которая ожидает указатель.

Таким образом, он функционально идентичен:

int blah = 1;
setsockopt(..., &blah, ...);

... за исключением того, что он работает без ввода blah.