Код компилируется, несмотря на получение адреса неправильных типов данных - PullRequest
2 голосов
/ 14 марта 2011
#include <iostream>
#define n 255

using namespace std;


int main()
{
int i=n;
int *ptr=&i;
int const *ptr_1=&i;
const int *ptr_2=&i;
const int * const ptr_3=&i;
}

Почему этот код компилируется в Visual C ++, Dev C ++ и G ++?Ссылка на - Ideone -

Ответы [ 4 ]

7 голосов
/ 14 марта 2011

Он компилируется, потому что все эти указатели эфира не изменяют const -квалификацию доступа к переменной или не применяют квалификацию, но никто из них не пытается ослабить квалификацию.

Например:

const int var;
int* address = &var; //illegal - tries to remove const

попытается получить неконстантный доступ к константной переменной, что недопустимо, но

int var;
const int* address = &var; //legal - only adds const

пытается получить постоянный доступ к неконстантной переменной, и это допустимо, поскольку неконстантная переменная допускает только константный доступ.

3 голосов
/ 14 марта 2011

Потому что в этом нет ничего плохого?

Одинаковые типы на обеих сторонах: int *ptr=&i;

Больше констант, совершенно нормально: int const *ptr_1=&i;

Точно так же, какстрока выше: const int *ptr_2=&i;

Больше констант, совершенно нормально: const int * const ptr_3=&i;

Вы всегда можете сделать переменную больше констант.

int const * i;
int * j = i;

Приведенное выше значение j меньше const и недействительно.

4.4 / 1: (охватывает int * до int const *)

Значениетипа «указатель на cv1 T» может быть преобразован в значение типа «указатель на cv2 T», если «cv2 T» более квалифицирован для cv, чем «cv1 T».

0 голосов
/ 14 марта 2011

C ++ позволяет создавать указатели на переменные, созданные в стеке. Таким образом, в этом коде нет ничего плохого. Более того, он часто используется для передачи параметров таким функциям, как WINAPI.

Если вопрос о семантике указателей, то ответ является полноценным. Например:

int * ptr; //pointer to a variable. Pointer and the variable can be changed.
int const * ptr; //a pointer to the constant variable, a pointer can be changed, the variable can not.
const int * ptr; //same as above.
const int * const ptr_3; //the most interesting section, a const pointer to const variable. 

Просто помните, что модификаторы перед * относятся к переменной, после нее - к указателю.

0 голосов
/ 14 марта 2011

Вы, вероятно, задаетесь вопросом, почему значение может быть принято const при получении адреса.

Это законно и известно как const продвижение на языке C ++.

Обратите внимание, что может произойти только продвижение одного уровня const, то есть int** может быть повышен до int* const*, но не до int const** (const придется «Сдвинуть» два места влево).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...