#c #pointers #initialization #constants #constexpr
#c #указатели #инициализация #константы #constexpr
Вопрос:
Я работал над упражнениями в C Primer и нашел онлайн-решения для упражнения 2.32.
Я понял, что следующий код был незаконным, потому что инициализация не может преобразовать из int в int*:
int null = 0, *p = null;
Однако два из упомянутых решений, которые я не придумал, были:
const int null3 = 0, *p3 = null3;
constexpr int null4 = 0, *p4 = null4;
Почему это позволяет это во время компиляции без ошибок? Я все еще ожидал, что инициализация p3 и p4 потребует amp; для обозначения адреса (amp;null3, amp;null4).
Вот код, который у меня есть из моего файла notepad:
#include <iostream>
int main()
{
// int null = 0, *p = null; // it is not legal; depending on intent there are two ways to fix (that I can think off atm)
{
int null = 0, *p = amp;null; // if the goal is to point to 'null'
}
{
int null2 = 0, *p2 = 0; // if the goal is to create a nullptr
}
{
const int null3 = 0, *p3 = null3; // if the goal is to create a nullptr
}
{
constexpr int null4 = 0, *p4 = null4; // if the goal is to create a nullptr
}
return 0;
}
Когда я запускаю через Microsoft Visual Studio CMDPrompt, это позволяет мне выполнять упражнение «cl» 2.32.cpp «»безошибочно.
Комментарии:
1.
const int null3 = 0, *p3 = null3;
это все еще выдает ошибку вы уверены, что она компилируется?2. без ошибок? Я не нашел компилятора, который его принимает: godbolt.org/z/aK1Gvz . Какой компилятор вы используете?
3. @D’Kayd: это не должно компилироваться.
4. абсолютно @Bathsheba
Ответ №1:
0
это один из способов обозначения константы нулевого указателя. (Это целочисленный тип, который равен нулю.) Другими словами, это особый случай, и вам разрешено присваивать ему тип указателя.
Компилятор, совместимый со стандартами, должен выдавать диагностику для присвоения типа указателя на null3
и null4
. (Он также должен выдать диагностику для int *p = 0;
.) Если у вас этого не происходит, проверьте, установлены ли соответствующие флаги компилятора.
Использование nullptr
намного лучше, хотя:
int *p = nullptr;
Комментарии:
1. «присвоить тип указателя
null3
» Я всегда путаюсь с этим, так что это может быть мой ограниченный английский, но разве не наоборот? «привязкаnull3
к указателю»?2. @idclev463035818: Вы можете сказать либо. Английский в этом смысле злой. Скорее похоже на C !
3. в этом случае я предпочитаю C
4. Как так? Литерал AFAIK 0 может использоваться как нулевой указатель для обратной совместимости в C , но не постоянная переменная int со значением 0 и не постоянное выражение int, например 1 — 1.
5. Правила для констант нулевого указателя были ужесточены в C 11; предыдущие версии допускали любое постоянное выражение rvalue значения 0, поэтому
могут разрешать использование.