Понимание 'const' на верхнем уровне, что может снизить удобочитаемость кода без улучшения правильности const

Обратите внимание на приведенный ниже код, в частности, на то, что get_length возвращает const size_t.

#include <stdio.h>

const size_t get_length(void)
{
    return 123;
}

void foo(void)
{
    size_t length = get_length();
    length++;
    
    printf("Length #1 is %zu\n", length);
}

void bar(void)
{
    // Still 123 because length was copied from get_length
    // (copy ellision notwithstanding, which is not the point here)
    size_t length = get_length();
    
    printf("Length #2 is %zu\n", length);
}

int main(void) {
    foo();
    bar();
}

Вывод:

Length #1 is 124
Length #2 is 123

Я получаю следующее предупреждение от clang-tidy:

Clang-Tidy: Return type 'const size_t' (aka 'const unsigned long')
is 'const'-qualified at the top level,
which may reduce code readability without improving const correctness

Это сообщение состоит из двух частей о возвращаемом типе:

  • Корректность констант не улучшена
  • Читаемость кода снижена

Я понимаю первую часть, где, как в foo и bar, поскольку вызывающим абонентам не требуется указывать свои локальные переменные как const, в конечном итоге правильность const не улучшается, т.е. нет ничего, что мешает вызывающим абонентам игнорировать тот факт, что вызываемый объект возвращает const объект.

Но я не уверен, что подразумевается под снижением читабельности кода - просто потому, что это может дать некоторым людям ложные ожидания, что возвращаемый тип никогда не будет изменен? Или есть что-то еще, что только начинает иметь смысл с более сложными типами возврата?

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


person Community    schedule 19.09.2020    source источник
comment
в чем причина использования здесь const? если его нет, это влияет на удобочитаемость.   -  person jdigital    schedule 19.09.2020
comment
@jdigital Как с точки зрения языка C мне объяснить вам, в чем причина использования const? Т.е. он уже говорит const. Что еще я могу вам рассказать, используя язык Си?   -  person    schedule 19.09.2020
comment
Я спрашиваю, почему вы решили использовать здесь const. вы могли пропустить это.   -  person jdigital    schedule 19.09.2020
comment
Дело не в этом. Я выбрал const, потому что это часть языка, и я пытаюсь понять это конкретное сообщение из clang-tidy. Код служит иллюстрацией.   -  person    schedule 19.09.2020
comment
@Terry Вам разрешено использовать const там, но Clang-Tidy также правильно отмечает это как неэффективное. См. Соответствующие Должны ли бесполезные квалификаторы типа для возвращаемых типов для ясности?, Преимущества использования const со скалярным типом?.   -  person dxiv    schedule 19.09.2020
comment
@dxiv Мне нравится термин "неэффективный", в этом есть смысл. Похоже, что это по сути повторяющийся вопрос, и если вы превратили свой комментарий в ответ, я был бы рад принять его.   -  person    schedule 19.09.2020


Ответы (2)


Вам разрешено использовать const там, но Clang-Tidy также правильно отмечает это как неэффективное.

Соответствующие вопросы и ответы в разделе Должны ли при возврате бесполезные квалификаторы типа типы используются для ясности?, Преимущества использования« const »со скалярным типом? частично объясняют, почему const неэффективен в этом контексте.

Другая часть вопроса о том, почему снижается читаемость кода, заключается в том, что лишний квалификатор const может потенциально отвлечь от основного факта, что постоянство не переносится через присвоение значений. Например, он может заставить клиентский код ошибочно полагать, что возвращаемое значение должно также использоваться как const, например const size_t val = get_length();, что не соответствует действительности, как показывает опубликованный код.

Аналогичное предостережение касается аргументов. Предположим, что возвращаемое значение const size_t get_length(); всегда передается другой функции baz(get_length());. Аргумент baz не нужно (и, возможно, не следует) объявлять как const size_t, а просто size_t, то есть void baz(size_t);.

person dxiv    schedule 19.09.2020
comment
Спасибо за объяснение, теперь все понятно! - person ; 19.09.2020

1. Корректность констант не улучшена

Возвращаемое значение можно использовать только как rvalue. Нет возможности изменить rvalue, поэтому корректность const уже указана.

2. Понижается читаемость кода.

Вы вводите читателя в заблуждение.

Примеры

/* the rest of your example... */

void baz(void)
{
    size_t length = get_length();
    length += 42;
    
    printf("Length #2 is %zu\n", length);
}

Нет ничего, что могло бы помешать смене length. Он инициализируется константой, верно, например size_t length = 123;

/* the rest of your example... */

void fu(void)
{
    const size_t length = get_length();
    length += 42; /* will give a compile-time error */
    
    printf("Length #2 is %zu\n", length);
}
person the busybee    schedule 19.09.2020
comment
Спасибо за ответ - в итоге я выбрал другой, потому что мне было немного легче понять, но и ваш тоже хороший! - person ; 19.09.2020