2013-03-10 6 views
2

Почему это работает? Я думаю, что глобальные данные «инициализируются» во время компиляции (компилятор сохраняет в .global раздел в obj формате файла пустые байты, поэтому, когда раздел загружается в память, он инициализируется нулем). Итак, как можно инициализировать указатель на адрес функции, если компилятор не знает, где функция будет находиться в памяти во время выполнения?C++ - глобальный указатель на функцию

#include <iostream> 

void vypis(); 

int neco; 
int * bla = &neco; 
void (*vypis_ptr)() = vypis; 

int main(int argc, const char * argv[]) 
{ 

} 

void vypis() { 

} 
+1

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

+1

@PhilH, конечно же, он должен, vypis_ptr - внешний вид видимого объекта. –

+7

Такое разрешение адреса не обязательно выполняется компилятором, а загрузчиком. Единственное, что нужно сделать до начала программы. Кроме того, по крайней мере теоретически эти вещи различны для C и для C++. В C++ это может быть даже конструктор, который будет запускаться после запуска программы, но до того, как он войдет в 'main'. –

ответ

4

я удалил излишним включать в iostream так, что ваш источник фактически составляет, как C и скомпилирован на моей системе к исполняемому называется vypis. Вот что я нашел:

$ nm vypis | fgrep vypis 
00000000004004d0 T vypis 
0000000000600888 D vypis_ptr 

Итак, vypis, функция, является глобальным в разделе «текст» и vypis_ptr, указатель на функцию, является глобальным в разделе «Данные».

Объекты в разделе данных имеют значения, хранящиеся в исполняемом файле, и я могу прочитать, что находится в vypis_ptr, выгрузив раздел данных с objdump.

$ objdump -d -j .data vypis 

vypis:  file format elf64-x86-64 


Disassembly of section .data: 

0000000000600878 <__data_start>: 
     ... 

0000000000600880 <__dso_handle>: 
     ... 

0000000000600888 <vypis_ptr>: 
    600888:  d0 04 40 00 00 00 00 00        [email protected] 

0000000000600890 <bla>: 
    600890:  a8 08 60 00 00 00 00 00        ..`..... 

Здесь мы можем видеть, что значение 4004d0 хранится в vypis_ptr, но это именно то место vypis, как показано на выходе nm.

+0

thx, я изучу эти утилиты – Krab

+0

hm, но почему есть имена моих переменных в файле obj ? – Krab

+0

@Krab Потому что они глобальны, и вы сделали их видимыми (не объявив их «статическими»), чтобы их можно было экспортировать и использовать в других модулях компиляции. И имена должны быть там, чтобы линкер мог найти символы. –

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