C++ Logo

std-proposals

Advanced search

Re: [std-proposals] RFC: Ignorable deprecation

From: Alberto Barbati <alberto_at_[hidden]>
Date: Thu, 14 Nov 2024 10:54:15 +0100
Il 13/11/2024 17:52, Arthur O'Dwyer ha scritto:
> On Wed, Nov 13, 2024 at 3:32 AM Alberto Barbati via Std-Proposals
> <std-proposals_at_[hidden]> wrote:
>
> Il 12/11/2024 17:21, Thiago Macieira via Std-Proposals ha scritto:
>> On Tuesday 12 November 2024 04:40:00 Pacific Standard Time Alberto Barbati via
>> Std-Proposals wrote:
>>> Hello everyone,
>>>
>>> I'd like to know if there's interest in introducing a way to selectively
>>> ignore the effects of the [[deprecated]] attribute. [...]
>> 3. Unit-testing the deprecated API itself.
>>> 2) Should we use a different attribute (as "deprecated_ignorable" above)
>>> or can/should we overload the existing [[deprecated]]?
>> I don't think so. Either you have a reason to ignore a deprecation or you
>> don't. The library author has already given you a heads up that this is either
>> going away or is obsolete for some reason (or actively dangerous).
>
> [...] Of course, the only solution is to write a paper :)
>
>
> I strongly encourage you to solve this at the toolchain level, not the
> ISO level.
> Basically what you're asking for is a way to "suppress" the
> deprecation warning for a specific component, for a specific stretch
> of (e.g. unit-testing) code.
> That's already possible today, using the tool specially designed for
> marking stretches of code:
>
> [[deprecated]] int f1();
> [[deprecated]] int f2();
> int f3();
> void test_f1() {
> #pragma GCC diagnostic push
> #pragma GCC diagnostic ignored("-Wdeprecated-declarations")
> f1(); f2(); f3();
> #pragma GCC diagnostic pop
> }

The very same objection was raised when I proposed the [[deprecated]]
attribute back in 2012 with N3394. Toolchains already had ways to mark
things as "deprecated", so why would C++ need an attribute? The answer
is now the same. The mere fact that the feature is avaiable in all
toolchains and is actually used extensively, despite the several
incompatible syntaxes and jumping through macro hoops, is a clear sign
that there is value in having a standard syntax. In this particular
case, it's even more compelling, since macros and pragma are unaware of
C++ scopes, so it's easy, for example, to forget a "#pragma GCC
diagnostic pop" or have the diagnostic suppressed in too much code than
intended.

> There is only one (theoretical?) problem with this solution: It's not
> fine-grained enough. It suppresses the warning about `f1`, yes, but it
> /also/ suppresses the warning about `f2`.
> What you're actually asking from the toolchain is a way to "whitelist"
> certain names — to say "I know I'm deliberately using /these/
> deprecated facilities, but please warn me about any /others/ I'm using
> accidentally."

Yes, I proposed something more fine grained, but Thiago made a good
point that this might be too much. Maybe having a simple "suppress all
deprecation" attribute can be enough. We can discuss this.

> That would look something like this:
>
> g++ -Wall -Wno-deprecated-declarations=f1
>
> and this:
>
> #pragma GCC diagnostic ignored("-Wdeprecated-declarations=f1")
>
> Now, when you actually get this feature into code review, the compiler
> devs will poke lots of holes in it. For one thing, what if the
> deprecated declaration is a member function, or a hidden friend, or an
> operator — how do you even spell the name of such a thing? Or what if
> there are two deprecated overloads, and you deliberately use one, but
> want to be warned about the other — how can you spell that?

I agree that this is not the way to do. In fact, that's not what
suggested in my original post. I did not use entity names but rather
"tags" directly on the deprecation itself. Not only it would not
introduce spelling issues, but could also be used to "group" toghether
deprecations.

> [[deprecated("Please switch to the path-taking one")]] int
> f4(std::string);
> [[deprecated("We don't support flags anymore")]] int
> f4(std::string, int flags);
> int f4(const std::filesystem::path&);
>
> I think concerns like this would probably stall an attempt to
> implement a fine-grained suppression mechanism.
> But if practical concerns would stall it at the compiler level,
> bringing it to WG21 is exactly the /most inappropriate/ approach. You
> should instead try to find something that you think /will/ work at the
> local level, implement it (or get it implemented), and /then/ see if
> programmers need it to be in the paper standard or not.

I did not suggest that, so I don't understand why I would need to try
something else "instead". I already did.

> Notice also that you are reinventing the classic tool named "lint
> <https://en.wikipedia.org/wiki/Lint_(software)>", which has many
> modern incarnations in different languages.
> Each "lint" variation has invented its own ways of indicating "I am
> deliberately doing [bad thing] on this line; please don't warn me
> about it."
> Here's the best man page I found in a quick search (for `flake8`, the
> Python linter):
> https://flake8.pycqa.org/en/3.1.1/user/ignoring-errors.html

Of course, I know lint, but you are comparing apple with oranges. Since
[[deprecated]] is in the language and there are at least three use cases
where we might want to ignore it (see my OP and Thiago's response) it
makes sense to have a way to suppress it in the language itself.

ab


Received on 2024-11-14 09:54:24