Почему адрес этой изменчивой переменной всегда равен 1?
Я хотел проверить адрес моей переменной
volatile int clock;
cout << &clock;
Но он всегда говорит, что x находится по адресу 1. Я что-то делаю неправильно?
Ответы
Ответ 1
iostreams будет отображать большинство указателей на void *
для отображения, но для указателей volatile
не существует никакого преобразования. Так как С++ возвращается к неявному приведению в bool
. Если вы хотите напечатать адрес, введите void*
явно:
std::cout << (void*)&clock;
Ответ 2
Здесь operator<<
для const void*
, но там нет operator<<
для volatile void*
, и неявное преобразование не удалит volatile
(он не удалит const
).
Как говорит GMan, cv-квалификация указанного типа не должна относиться к делу печати адреса. Возможно, перегрузка, определенная в 27.7.3.6.2, должна быть operator<<(const volatile void* val);
, я не могу сразу увидеть какой-либо недостаток. Но это не так.
#include <iostream>
void foo(const void *a) {
std::cout << "pointer\n";
}
void foo(bool a) {
std::cout << "bool\n";
}
int main() {
volatile int x;
foo(&x);
std::cout << &x << "\n";
int y;
foo(&y);
std::cout << &y << "\n";
void foo(volatile void*);
foo(&x);
}
void foo(volatile void *a) {
std::cout << "now it a pointer\n";
}
Вывод:
bool
1
pointer
0x22cd28
now it a pointer
Ответ 3
Это связано с тем, что нет перегрузки для operator <<
, которая принимает указатель на volatile
, и нет никакого преобразования указателя, которое могло бы удовлетворить его.
Согласно стандарту С++,
для любого типа T
, указатель на T
, указатель на const T
, а указатель на volatile T
считаются отдельными типами параметров, как ссылка на T
, ссылка на const T
и ссылка до volatile T
.
Оператор <<
не имеет перегрузки для указателей на нестатический элемент, указывает на изменчивые или указатели на функции, поэтому попытка вывода таких объекты вызывают неявное преобразование в bool
.