присваивание от константного указателя на символ до указателя не дает предупреждений - PullRequest
0 голосов
/ 17 июня 2019

Почему следующий код не вызывает предупреждений?

Скомпилировано с -Wall, -Wpedantic, -Wextra, и ни один из них не выдает предупреждение.

int main()
{
    const char *p;
    char a[] = "hey";
    p = a;
    (void) p;
    return 0;
}

Я бы ожидал какое-то предупреждение, например, присваивание -Wdiscarded-qualifiers

Ответы [ 3 ]

6 голосов
/ 17 июня 2019

Вы назначаете от a char * до a const char *.Это безопасно, потому что вы добавляете квалификатор const, а не удаляете его.

Если вы сделали это:

char *p;
const char a[] = "hey";
p = a;

Тогда вы получите предупреждение об отмене квалификатора const.

1 голос
/ 17 июня 2019

Вы не отбрасываете квалификатор.Вы добавляете один.Эта функция на самом деле очень важна.Это один из тех немногих случаев, когда C предлагает программисту разумную возможность защитить себя от самого себя.Например, взгляните на прототипы для функций манипуляции со строками в стандартной библиотеке:

char * strcpy ( char * destination, const char * source );

Это дает нам информацию о том, что destination будет изменено, но source не будет.

Из комментария ниже:

Требуется ли также, чтобы параметр назначения не мог быть константным символом *

Есть способы обойти это, поэтому это не требуется само по себе.Мы говорим на C в конце концов.Но если вы планируете использовать аргумент в качестве выходного аргумента, он не должен быть объявлен как const.Вот пример, где я использую аргумент const в качестве выходного параметра.Это функция, которая устанавливает длину строки в ноль:

// Note: Bad code. Do not do this at home. Ok, do it at home,
// but do not do it at work.
void removeString(const char * s)
{
    char *p = (char*) s;
    p[0] = 0;
}

Но для того, чтобы сделать это, вы должны сначала объявить указатель на неконстантный, указывающий на s, а затем вы должны добавитьбросок (char*), чтобы избавиться от предупреждения.Это легко сделать, но это довольно сложно сделать по ошибке, поэтому он служит довольно хорошей защитой.

Объявление аргумента в качестве указателя на const дает две вещи:

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

  2. Это затрудняет (но не делает невозможным) изменение чего-либо, что вы не должны менять по ошибке в функции.

0 голосов
/ 17 июня 2019
 assignment from const char pointer to char pointer gives no warnings

Ваш пример делает что-то противоположное. Вы назначаете указатель на постоянный объект с указателем на не постоянный объект. Так что вы ничего не выбрасываете, следовательно, не беспокойтесь

...