Я наткнулся на фрагмент кода void *p = &&abc;
. Каково значение &&
здесь?
Я знаю о ссылках rvalue, но я думаю, что &&
, используемые в этом контексте, различны. Что означает &&
в void *p = &&abc;
?
Что означает && в void * p = && abc;
Ответ 1
&&
- расширение gcc, чтобы получить адрес метки, определенный в текущей функции.
void *p = &&abc
является незаконным в стандартных C99 и С++.
Это компилируется с g++.
Ответ 2
Как найти
Это адрес метки, и это функция, характерная для GCC.
int main(void) {
void* startp;
s:
startp = &&s;
printf("the assignment above starts at address %p\n", startp);
return 0;
}
Вы могли бы подумать о себе, протестировав:
int main(void) {
void* startp;
int a;
startp = &&a;
printf("startp=%p\n", startp);
return 0;
}
В этом случае GCC говорит:
error: label 'a used, но не определен
Под капотом - сборка
Вам нужно знать ассемблера, чтобы это понять, но я попытаюсь объяснить вам, что означает адрес метки.
После того, как ОС загрузит файл .exe с диска, компонент операционной системы, называемый "загрузчиком" (в Windows есть "загрузчик PE", linux имеет "загрузчик ELF" или, возможно, даже другие, если они скомпилированный в ядре), он выполняет "виртуализацию" этой программы, превращая ее в процесс.
Этот процесс считает, что он единственный в ОЗУ и имеет доступ ко всей ОЗУ (то есть 0x00000000-0xFFFFFFFF на 32-разрядной машине).
(вышесказанное представляет собой лишь краткое описание того, что происходит, вам действительно нужно научиться сборке, чтобы полностью ее понять, так что несите меня)
Теперь метка в исходном коде является в основном адресом. "goto label"; не делает ничего, кроме перехода на этот адрес (подумайте о указателе инструкции в сборке). Этот ярлык хранит этот адрес RAM и что вы можете узнать этот адрес.
После того, как вы узнали ASM, вы поймете, что этот адрес указывает на инструкцию в разделе .text
исполняемого файла. Раздел .text
- это тот, который содержит исполняемый программный (двоичный) код.
Вы можете проверить это с помощью
objdump -x a.out
Практический пример
Как описано в GCC, вы можете использовать это для инициализации таблицы перехода. Некоторые генераторы сканеров такие как re2c (см. Параметр -g
), используют это для создания более компактных сканеров, Может быть, даже генератор синтаксического анализа использует ту же технику.