Там какой-либо путь состоит в том, чтобы найти адрес ссылки?

Похоже, в вашем проекте есть библиотека типа ShowTime .

В ShowTime вы можете разрешить его показ только в отладке:

ShowTime.enabled = .debugOnly

64
задан merlin2011 6 March 2015 в 00:44
поделиться

8 ответов

Ссылки не имеют собственных адресов. Несмотря на то, что ссылки могут быть реализованы в виде указателей, в этом нет необходимости и гарантии.

В C++ FAQ лучше всего сказано:

В отличие от указателя, когда ссылка является привязанный к объекту, это не может быть "перезагрузка" на другой объект. сама по себе ссылка не является объектом (она не имеет документов, удостоверяющих личность; берет адрес в справке указан адрес референт; помните: ссылка является его референтом).

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

Ссылка на него

64
ответ дан 24 November 2019 в 15:45
поделиться

При реализации ссылки как член структуры затем можно получить ее адрес:

struct TestRef{
  int& r;
  int i;
  TestRef(int& ref): r(ref){
  }
};

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

Теперь, адрес ссылочного TestRef.r является адресом объекта TestRef. Поскольку r является первым членом TestRef.

можно повторно присвоить ссылку путем обновления хранилища значения в памяти TestRef.r.

Этот код ниже показывает, что можно получить адрес ссылки и Вас и повторно присвоить ссылку на переменную различия.Примечание: моей ОС является ОС X64 (я использую XCode MacBook Pro 2015, MacOs 10.15.1).

#include <iostream>
using namespace std;

struct TestRef{
  int& r;
  int i;
  TestRef(int& ref): r(ref){}
};

int main(int argc, const char * argv[]) {
  int i = 10;
  int j = 11;
  TestRef r(i); // r.r is reference to i

  cout << r.r << " " << i << " " << j << endl; // Output: 10 10 11

  int64_t* p = (int64_t*)&r; // int32_t in 32 bit OS; 
  // Note: 
  // p is the address of TestRef r and also the address of the reference r.r
  // *p is the address of i variable
  //
  // Difficult to understand? r.r indeed a pointer to i variable 
  // *p will return the address inside the memory of r.r
  // that is the address of i variable
  // this statement is true: *p == &i  
  // ------>
  // now we change the value of *p to the address of j 
  // then r.r will be the reference of j instead the reference of i

  *p = (int64_t)&j;          // int32_t in 32 bit OS; 

  cout << r.r << " " << i << " " << j << endl; // Output: 11 10 11
  return 0;
}

Поэтому на самом деле можно работать вокруг, чтобы повторно присвоить ссылку, как хакер.

0
ответ дан 24 November 2019 в 15:45
поделиться

Как говорит Бьярне Струструп в TC++PL, ссылку можно считать просто другим именем для существующей сущности (объекта или функции). Хотя это не всегда самое точное описание лежащего в основе низкоуровневого механизма, реализующего ссылки, это очень хорошее описание концепции, которую эти ссылки призваны реализовать на языковом уровне. Неудивительно, что язык не предоставляет средств для получения адреса самой ссылки.

На уровне языка ссылка не гарантированно занимает место в хранилище, поэтому в общем случае она не имеет адреса.

.
12
ответ дан 24 November 2019 в 15:45
поделиться

Просто используйте оператор '&'. Например :

int x = 3;
int &y = x;
cout<<&y<<endl;

Это вернет адрес x, так как y не более, чем адрес x.

.
7
ответ дан 24 November 2019 в 15:45
поделиться

Не надежно, т.к. ссылки не должны иметь уникального местоположения в адресной памяти.

4
ответ дан 24 November 2019 в 15:45
поделиться

Не в одиночку. Если вам нужен его "адрес", засуньте его в структуру или класс. Даже в этом случае это не гарантирует, что вы окажетесь в непосредственной близости от того, что вы, вероятно, хотите сделать с помощью указателя. Если вы хотите доказательство, размер ссылки равен типу ссылки. Попробуйте с помощью char & see.

3
ответ дан 24 November 2019 в 15:45
поделиться

В стандарте ИСО лучше всего сказано:

Здесь не должно быть ни ссылок, ни массивов ссылок, ни указателей на ссылки.

Мне не нравится логика, которую многие здесь используют, что вы не можете этого сделать, потому что ссылка не "гарантированно где-нибудь будет просто указателем". Точно так же как int x может быть только регистром процессора без адреса, но при использовании и x магически становится ячейкой памяти, компилятор все равно может разрешить то, что Вы хотите.

Раньше многие компиляторы разрешали именно то, что Вы просили, например

int x, y;
int &r = x;
&r = &y; // use address as an lvalue; assign a new referent

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

22
ответ дан 24 November 2019 в 15:45
поделиться

Можно перехватить импорт и из... import , определив собственную функцию __ import __ и назначив ее __ builtin __. __ import __ (обязательно сохраните предыдущее значение, так как переопределение, несомненно, захочется делегировать ему; и вам потребуется импортировать __ builtin __ , чтобы получить модуль builtin-objects).

Например (Py2.4 specific, поскольку это то, о чем вы спрашиваете), сохраните в aim.py следующее:

import __builtin__
realimp = __builtin__.__import__
def my_import(name, globals={}, locals={}, fromlist=[]):
  print 'importing', name, fromlist
  return realimp(name, globals, locals, fromlist)
__builtin__.__import__ = my_import

from os import path

и теперь:

$ python2.4 aim.py
importing os ('path',)

Таким образом, это позволяет перехватить любой конкретный запрос на импорт и изменить импортированный модуль [s], как вы хотите, прежде чем вернуть их - см. спецификации здесь . Это тот «крючок», который вы ищете, верно?

-121--4349843-

Да. но с оговоркой. Идея о том, что закольцовывание назад быстрее никогда не применяется ко всем старым процессорам. Это x86 вещь (как в 8086-486, возможно Pentium, хотя я не думаю больше).

Эта оптимизация никогда не применялась к какой-либо другой архитектуре ЦП, о которой я знаю.

Вот почему.

Регистр 8086 был специально оптимизирован для использования в качестве счетчика циклов. Вы помещаете счетчик циклов в CX, а затем есть несколько инструкций, которые уменьшают CX, а затем устанавливают коды условий, если они равны нулю. Фактически, существовал префикс команды, который можно было поставить перед другими командами (префикс REP), которые в основном итерируют другую команду, пока CX не достигнет 0.

Еще в те дни, когда мы подсчитывали команды и инструкции, были известны фиксированные счетчики циклов с использованием cx в качестве счетчика циклов, и cx был оптимизирован для подсчета.

Но это было давно время назад. С тех пор как Pentium, эти сложные команды были в целом медленнее, чем использование большего количества и более простых инструкций. (RISC ребенок!) Ключевая вещь, которую мы пытаемся сделать в эти дни, - это попытаться поставить некоторое время между загрузкой регистра и его использованием, потому что трубопроводы на самом деле могут делать несколько вещей за цикл, пока вы не пытаетесь использовать один и тот же регистр для нескольких вещей одновременно.

В настоящее время убивает производительность не сравнение, а ветвление, и только тогда, когда предсказание ветви предсказывает неверное.

-121--1709643-

НЕТ . Нет пути получить адрес ссылки.
Это связано с тем, что ссылка не является объектом, а является псевдонимом (это означает, что это другое имя для объекта).

int  x = 5;
int& y = x;

std::cout << &x << " : " << &y << "\n";

Будет выведен тот же адрес.
Это связано с тем, что «y» является просто другим именем (псевдонимом) для объекта «x».

35
ответ дан 24 November 2019 в 15:45
поделиться
Другие вопросы по тегам:

Похожие вопросы: