Почему const char [] постоянно конвертируется в const char *? - PullRequest
2 голосов
/ 18 марта 2020

Итак, я знаю, что строковый литерал имеет тип const char[N]. И я также знаю, что если мы получили параметр const char[] в некоторой функции, компилятор автоматически преобразует его в const char*.

Но почему я всегда получаю сообщения об ошибках компилятора о том, что строковый литерал имеет тип const char*?

Вот несколько примеров:

void f(int x) {}
int main()
{
    f("Hello");
    return 0;
}

ОШИБКА: invalid conversion from 'const char*' to 'int'

void f() {
    throw "Hello";
}
int main()
{
    try{ f(); } catch (int x) { std::cout << "No\n";}
    return 0;
}

В терминале: terminate called after throwing an instance of 'char const*'

РЕДАКТИРОВАТЬ: я использую GNU G CC.

1 Ответ

5 голосов
/ 18 марта 2020

Почему const char [] все время преобразуется в const char *? 1002 *

В общем, потому что есть другое правило, тесно связанное с упомянутой вами настройкой параметра функции:

[conv.array] Преобразование массива в указатель

Значение l или значение типа «массив NT» или «массив неизвестной границы T» можно преобразовать в prvalue типа «указатель на T». Временное преобразование материализации ([conv.rval]) применяется. Результатом является указатель на первый элемент массива.

[basi c .lval] Категория значения

Всякий раз, когда glvalue появляется как операнд оператора, который ожидает значение prvalue для этот операнд, стандартное преобразование lvalue-to-rvalue, array-to-pointer или функция-указатель применяются для преобразования выражения в значение.

В разговорной речи это неявное преобразование называется указателем с затуханием .

Появляется сообщение об ошибке, описывающее попытку преобразования этого промежуточного результата преобразования lvalue-to-rvalue в тип параметра.

В терминале: завершение вызова после выброса экземпляра 'char const *'

В этом конкретном случае выброса исключения существует специальное правило c, которое по сути то же самое как указатель затухающий, но в контексте броска:

[expr.throw] Бросок исключения

Оценка выражения броска с операндом выдает исключение ption; тип объекта исключения определяется с помощью удаления любых cv-квалификаторов верхнего уровня из типа операнда stati c и корректировки типа из «массива T» или тип функции T для «указатель на T» .

Итак, скорректированный тип объекта исключения на самом деле const char*, и именно этот необработанный объект описывает сообщение, сгенерированное компилятором.


Для полноты, вот правило корректировки параметров, которое вы знали:

[dcl.fct] Функции

... После определения типа каждого параметра любой параметр типа «массив T» »Или типа функции T настроен так, чтобы он был« указателем на T »

PS. Для обработчиков исключений также существует аналогичное правило настройки:

[исключением. Дескриптор] Обработка исключения

Обработчик типа «массив T» или типа функции T настроен на тип «указатель на T».

...