const только для чтения локальные копии - PullRequest
1 голос
/ 31 мая 2010

gcc 4.4.4 c89

Мне просто интересно, стоит ли передавать const в функцию.

т.е.

void do_something(const char *dest, const int size)

Размер только для чтения, поэтому я не хочу его менять. Тем не менее, некоторые разработчики никогда не имеют этого, так как const имеет локальную копию, которая используется. Указатель постоянный, так как вы можете изменить значение в вызывающей подпрограмме.

У меня всегда есть const для локальных копий, доступных только для чтения, поскольку это подтверждает, что любой, кто читает мой код, является переменной только для чтения. А также, когда я пишу код, я не ошибаюсь, изменяя его, не осознавая.

Большое спасибо за любые предложения,

Ответы [ 4 ]

4 голосов
/ 31 мая 2010

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

Что бы вы ни делали, вы должны опустить const в объявлении функции в заголовке. const должен быть частью только в определении функции. В C (и C ++ тоже) есть правила, делающие эту совместимость (т. Е. const для параметра значения игнорируется (когда он влияет на параметр только на его верхнем уровне) для объявлений чистой функции, которые не имеют тела). Обоснование состоит в том, что такой const ничего не изменит в отношении вызывающей стороны и, таким образом, является подробностью реализации вызываемой функции.

Это не относится к вашему первому параметру. Любой способный разработчик, которого я знаю, поместит эту константу туда, потому что это дает важную гарантию вызывающей стороне вашей функции (что она не изменит данные, на которые указывает то, что передается). Имя вашего параметра, однако, кажется немного странным, потому что оно указывает, что функция должна записать то, на что указывает.

Обратите внимание, что для того, чтобы быть последовательным, вы должны сделать первый параметр сам по себе также константным, как вы сделали со вторым параметром. Таким образом, это стало бы (переименование его в «источник», чтобы избежать путаницы).

void do_something(const char * const source, const int size)
3 голосов
/ 31 мая 2010

Лично мне нравится ставить const на как можно большее количество переменных - я редко меняю значение переменной после ее присвоения. (Одним заметным исключением являются, конечно, счетчики / итераторы цикла.)

По крайней мере, это значительно улучшает возможность отладки, поскольку гарантирует, что значения не могут быть изменены. Это значительно облегчает отслеживание состояния выполнения. Это также улучшает читабельность, поскольку сигнализирует о намерении работать с неизменяемыми значениями.

Следовательно, я делаю то же самое для параметров функции. В конце концов, они ведут себя как обычные переменные внутри функции.

С другой стороны, это чертовски запутывает многих других программистов, поэтому в большинстве совместных проектов я воздерживаюсь от этого; это нарушит последовательность и будет контрпродуктивным.

1 голос
/ 31 мая 2010

По моему мнению, нет смысла объявлять const ни на чем другом, кроме остроконечной области. Скалярные параметры (и даже указатели) являются локальными копиями с теми же ограничениями, что и другие локальные переменные. На самом деле они являются локальными переменными, и иногда их целесообразно использовать и модифицировать, чтобы избежать ненужных копий их значений.

char * strcat(char *d, const char *s)
{
  char *p = d;

  while(*p) p++;
  while(*s) *p++ = *s++;
  *p = 0;
  return d;
}


char * strcat(char *d, const char *s)
{
char *p = d;
const char *s2 = s;

  while(*p) p++;
  while(*s2) *p++ = *s2++;
  *p = 0;
  return d;
}

Второй вариант действительно лучше? Я так не думаю.

При использовании старого синтаксиса K & R более очевидно, что они являются локальными переменными функции.

char * strcat(d, s)
char *d;
const char *s;
{
...
1 голос
/ 31 мая 2010

Так называемая «правильность констант» очень важна, особенно если вы создаете какой-то модуль (например, dll), где его будут использовать другие люди. Это значительно облегчает понимание цели функции и помогает предотвратить некоторые странные ошибки (среди прочего). Так что да, я бы определенно предложил использовать модификатор const, где это применимо.

РЕДАКТИРОВАТЬ: теперь, присмотревшись к заголовку функции, кажется, что "dest" - это то, что функция должна изменить. Тогда объявление его как const кажется странным.

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