Пометить как устаревшие параметры функции в С++ 14

Читая эту запись в блоге и комментарии к ней, я заметил, что она дает в качестве примера возможность пометить определенные параметры функции как устаревшие, как в (пример взят из поста):

// Deprecate a function parameter
int triple([[deprecated]] int x);

Теперь мне было интересно, каков хороший вариант использования такой функции? Никто в комментариях к этому посту или где-либо еще, что я искал, похоже, не имеет ни малейшего представления.

РЕДАКТИРОВАТЬ:

Чтобы увидеть это в действии, есть компилируемый пример для goldbolt.


person bracco23    schedule 28.05.2019    source источник
comment
Хм. Я думал об аргументах по умолчанию, но gcc не предупреждает ни о каком утверждении в void f([[deprecated]] int n = 0); void g() { f(); f(2); }. Он только предупреждает в теле функции.   -  person aschepler    schedule 28.05.2019
comment
При использовании магистрали gcc, как вы можете видеть для goldbolt, выдается предупреждение, когда параметр используется внутри функции, а не по вызову, вот почему это вызывает недоумение.   -  person bracco23    schedule 28.05.2019
comment
Почему вы предполагаете, что есть вариант использования? Может быть, это возможно только потому, что не было сделано исключения, запрещающего это.   -  person eerorika    schedule 28.05.2019
comment
@eerorika Я не предполагаю, что есть вариант использования. Вполне возможно, что эта функция просто оказалась доступной без какого-либо планирования, и оставить ее как есть не вредно, но мне любопытно узнать, есть ли на самом деле вариант использования.   -  person bracco23    schedule 28.05.2019


Ответы (3)


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

Исходное предложение, N3394, не упоминает такой вариант использования, как и документация для исходной функции в GCC (который независимо принимает эквивалентное использование) или в VS (я не проверял Clang).

Таким образом, я думаю, что это «случайность», что это разрешено, а не то, что кто-то действительно считал полезным.

Может быть полезно документировать устаревшие аргументы по умолчанию, как исследует Artyer? Да, потенциально, и неопределенно. Но, как также обнаружил Артьер, основные компиляторы на самом деле не реагируют на такое использование полезным образом.

Таким образом, в настоящее время это бесполезно, и языковая функция не была специально разработана, чтобы быть полезной в этом случае.

person Lightness Races in Orbit    schedule 28.05.2019
comment
Хотя я понимаю, как такой поворотный случай может произойти без планирования, я думаю, что маловероятно, что он оставался незамеченным все это время. Любая ссылка на него в каком-то обсуждении после того, как он был представлен? - person bracco23; 28.05.2019
comment
Я не думаю, что это не было замечено, я думаю, что вы просто первый, кто заботится :P В конце концов, есть много других бесполезных фрагментов кода, которые мы можем написать, и это зависит от нас как отдельных лиц. Другими словами: зачем писать в языке специальное правило, запрещающее это? Что мы выиграем от такого осложнения? Это действительно суть. - person Lightness Races in Orbit; 28.05.2019

Скажем, у вас была такая функция:

void* allocate(std::size_t sz, void* hint = nullptr) {
    // if you give `hint` it *might* be more efficient
}

А потом вы решили, что больше не стоит пытаться делать вещи, основанные на hint. Итак, вы бы сделали это:

void* allocate(std::size_t sz, [[deprecated]] void* hint = nullptr) {
    // `hint` is ignored. The compiler warns me if I use it in the
    // function body accidentally, and people reading the function
    // signature can see that it is probably going to be ignored.
}

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

Но это в основном для разработчиков функции, а не для пользователей функции, в будущем, чтобы они знали, почему существует кажущийся «бесполезным» параметр.

Я также думаю, что это отключит предупреждение «неиспользуемый параметр» с флагом -Werror=unused-parameter в gcc/clang, но это не так. Использование (void) deprecated_parameter также выдает предупреждение об использовании устаревшего параметра, так что это похоже на ошибку. Если бы он отключил предупреждение о неиспользуемом параметре, это был бы еще один вариант использования [[deprecated]].

person Artyer    schedule 28.05.2019
comment
Но ни clang++, ни g++ фактически не предупреждают о каких-либо вызовах функции, независимо от того, дают ли они аргумент для hint. - person aschepler; 28.05.2019
comment
@aschepler Да, потому что этот параметр в любом случае передается всегда (даже если он неявно находится на стороне вызывающей стороны из-за параметра по умолчанию), и он отличается от того, что вся функция устарела. Это больше похоже на то, что это устарело внутри тела функции, но вызывающей стороне не всегда нужно заботиться об этом. - person Artyer; 28.05.2019
comment
Это аккуратно. Но это не так идиоматично, как простое удаление имени параметра после его очистки. - person StoryTeller - Unslander Monica; 28.05.2019

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

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

person Rene    schedule 28.05.2019
comment
Но и g++, и clang++ предупреждают только об использовании параметра в определении этой функции, а не о любых вызовах функции, независимо от того, предоставляют ли они аргумент для этого параметра. Это противоположно тому, что вы описываете. - person aschepler; 28.05.2019