Почему глобальные функции могут вызываться с двумя разными адресами, но у global int есть только один, но у статических функций тоже есть один?

#c #c 14

#c #c 14

Вопрос:

Вот простой пример кода:

 #include lt;iostreamgt;  int hello_world(float j) {  std::cout lt;lt; j lt;lt; std::endl;  return 12; }  int myvar = 123;  int main() {  // vs19 debugger watch: (myvar_ptr == amp;myvar) is true  auto myvar_ptr = amp;myvar;   // vs19 debugger watch: (hw_ptr == amp;hello_world) is false, but function on this new address is hello_world  auto hw_ptr = amp;hello_world;   hw_ptr(10);   int myvar_value = *myvar_ptr;   system("pause"); // breakpoint }  

Как вы можете видеть — адрес hello_world функции, извлеченной внутри main, и адрес, который я вижу в отладчике, — это два разных адреса, но для myvar них они одинаковы, почему? Когда я добавляю static ключевое слово в объявление функции — эти два адреса становятся равными, почему?

Вот список наблюдения:

введите описание изображения здесь

введите описание изображения здесь

введите описание изображения здесь

введите описание изображения здесь

Комментарии:

1. Почему вы указываете на — это ужасная идея, тем более, что она может быть недостаточно большой для хранения адреса int int

2. Я знаю, но код предназначен только для тестирования, я просто хочу понять, как работают указатели, вот и все

3. Вы не можете сделать такие выводы, наблюдая за неопределенным поведением. Нет никакого неправильного поведения, когда поведение не определено.

4. Ваш код нарушен из-за этих «целей тестирования». На самом деле GCC категорически отвергает его компиляцию. Если вы хотите привести указатель к интегралу, вам нужно использовать что-то подходящее, например uintptr_t . Кроме того, сравнение целого числа с указателем, с которым вы, похоже, работаете, myvar_addr == amp;myvar не допускается в C

5. Я не знаю терминологии Windows, но часто функция имеет 2 адреса: один, где находится фактический код, и один для функции PLT.