Почему передача аргумента константного указателя в объявлении функции не имеет никакого эффекта - PullRequest
0 голосов
/ 10 апреля 2019

Описание проблемы

У меня есть функция, которая получает константный указатель на константный двойной массив, в котором я зацикливаюсь, используя размер в качестве проверки границы внутри my_func.

Декларация в .ч

void my_func(const double * const my_array, size_t size);

Реализация в .c

void my_func(const double * const my_array, size_t size) {
  for (size_t idx = 0; idx < size; idx++) {
    do_something_with(my_array[idx]);
  }
}

Я не хочу, чтобы указатель был изменен внутри функции, следовательно, делая его * const. Я не хочу, чтобы данные, на которые он указывает, были изменены, поэтому const double.

Clang-Tidy, однако, хочет, чтобы у меня была функция объявление отбрасывает константу на указателе, делая ее

void my_func(const double * my_array, size_t size);

Clang-Tidy: параметр 'my_array' является const-квалифицированным в объявлении функции; const-квалификация параметров влияет только на определения функций

Если я следую этому совету, но хочу сохранить свои ограничения сверху, мои объявление функции и определение больше не совпадают.

Вопросы

1)
Предположим, что мой аргумент-указатель не является константой (const double * pointer_arg), если я изменю pointer_arg внутри функции, чтобы она указала на другой const double, будет ли изменение видимо за пределами моей функции? То есть, после строки, в которой я выполнил свою функцию, где заполнение указывает pointer_arg? Если он не виден, означает ли это, что указатель копируется по значению? Это вообще возможно?

2)
Какова причина решения, которое const в декларации не имеет никакого эффекта?

3)
В чем может быть преимущество наличия другой подписи функции в объявлении и определении? Для меня, глядя на мой заголовочный файл, не ясно, как работает реализация, будет ли она const внутри функции, не так ли? Это вызывает путаницу у меня или соавтора над кодом.

4)
Должен ли я опустить const в декларации? Каковы лучшие практики в этом случае?

Ответы [ 2 ]

5 голосов
/ 10 апреля 2019

1) Предположим, что мой аргумент указателя не является const (const double * pointer_arg), если я изменю pointer_arg внутри функции, чтобы он указывал на другой const double, будет ли это изменение видимым вне моей функции?

Нет, его не видно.

То есть, после строки, где я выполнил свою функцию, куда указывает fill_arg?

То же, что и раньше.

Если он не виден, означает ли это, что указатель копируется по значению?Возможно ли это вообще?

Именно так.

2) В чем причина того, что const в объявлении не действует?

Поскольку оно передается по значению, const не влияет (на вызывающего).

3) Что может быть полезным, если подпись другой функциив декларации и определении?

Нет.На самом деле он даже не должен компилироваться в C ++.

4) Должен ли я удалить const в объявлении?Каковы лучшие практики в этом случае?

Да, вы должны отбросить const, потому что это не очень помогает.Вы только запрещаете, чтобы функция изменяла свою копию указателя, что не имеет значения для вызывающей стороны.

0 голосов
/ 10 апреля 2019

Атрибут const справа от * влияет только на сам указатель, а не на указанную память, сам указатель сохраняется как автоматическая переменная.

void my_func(const double * my_array, size_t size);

То же самоеas

void my_func(const double * const my_array, size_t size);

Константа влияет только на реализацию, где используется my_array.my_array имеет автоматическую продолжительность хранения и не может быть изменена в реализации, когда к нему применяется const.

Данный прототип:

int add(int a, int b);
// same as
int add(int const a, int const b);

Полезное использование, принудительное сохранение параметровa & b константа внутри функции:

int add(int const a, int const b) {
    // a = a*b; // error
    return a+b;
};
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...