52

One way to implement deprecation warnings is to produce warnings on calls to deprecated functions, unless you are calling from a deprecated context. This way legacy code can call legacy code without producing warnings that only amount to noise.

This is a reasonable line of thinking, and it is reflected in the implementations I see in GCC 4.2 (1) and Clang 4.0 (2) on OS X as well as Clang 3.0 (3) on Ubuntu.

  • (1): i686-apple-darwin11-llvm-g++-4.2 (GCC) 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.11.00)
  • (2): Apple clang version 4.0 (tags/Apple/clang-421.0.57) (based on LLVM 3.1svn)
  • (3): Ubuntu clang version 3.0-6ubuntu3 (tags/RELEASE_30/final) (based on LLVM 3.0)

However, when I compile with GCC 4.6 (4) on Ubuntu, I get deprecated warnings for all invocations of deprecated functions, independently of context. Is this a regression in functionality? Are there compiler options I can use to get the other behavior?

  • (4): g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3

Example program:

int __attribute__((deprecated)) a() {
    return 10;
}

int __attribute__((deprecated)) b() {
    return a() * 2; //< I want to get rid of warnings from this line
}

int main() {
    return b(); //< I expect a warning on this line only
}

Output from GCC 4.2 (Yes, I do get the same warning twice. I don't care about that, though):

main.cpp: In function ‘int main()’:
main.cpp:10: warning: ‘b’ is deprecated (declared at main.cpp:5)
main.cpp:10: warning: ‘b’ is deprecated (declared at main.cpp:5)

Output from GCC 4.6:

main.cpp: In function 'int b()':
main.cpp:6:9: warning: 'int a()' is deprecated (declared at main.cpp:1) [-Wdeprecated-declarations]
main.cpp:6:11: warning: 'int a()' is deprecated (declared at main.cpp:1) [-Wdeprecated-declarations]
main.cpp: In function 'int main()':
main.cpp:10:9: warning: 'int b()' is deprecated (declared at main.cpp:5) [-Wdeprecated-declarations]
main.cpp:10:11: warning: 'int b()' is deprecated (declared at main.cpp:5) [-Wdeprecated-declarations]

How can I convince GCC 4.6 that it should give me the same output as GCC 4.2?

Magnus Hoff
  • 21,529
  • 9
  • 63
  • 82
  • It's entirely possible that this never worked with FSF GCC, that the 4.2 behaviour you're seeing is an Apple patch to GCC. Do you happen to have FSF GCC 4.2 installed anywhere to check? –  Nov 19 '12 at 18:26
  • @hvd You're right. I'd like to see that test, but I do not have 4.2 on hand :/ – Magnus Hoff Nov 19 '12 at 18:59

4 Answers4

62

-Wno-deprecated will remove all deprecated warnings

doron
  • 27,972
  • 12
  • 65
  • 103
61

gcc 4.6 added diagnostic pragmas that will help solve this problem:

#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wdeprecated-declarations"
int __attribute__((deprecated)) b() {
   return a() * 2; //< I want to get rid of warnings from this line
}
#pragma GCC diagnostic pop

Note: This only works in gcc 4.6 and higher. The push and pop are 4.6 extensions. With gcc 4.5, the #pragma GCC diagnostic push and pop will be ignored (with warnings). What won't be ignored is the #pragma GCC diagnostic ignored "-Wdeprecated-declarations" -- but now this has effect until end of file.

David Hammen
  • 32,454
  • 9
  • 60
  • 108
  • 2
    +1 - This is a really good solution for those not wanting to or not able to patch GCC. – Riot Jun 30 '13 at 15:45
  • +1 [Works with clang, too.](https://clang.llvm.org/docs/UsersManual.html#controlling-diagnostics-via-pragmas) – Mark Gates May 23 '23 at 04:57
20

The behaviour you're seeing in GCC 4.2 is caused by an Apple-specific patch to GCC. FSF GCC 4.2.4 warns about the use of a. The specific bit that Apple GCC has that FSF GCC doesn't is:

--- a/gcc/toplev.c
+++ b/gcc/toplev.c
@@ -902,6 +902,9 @@ warn_deprecated_use (tree node)
   if (node == 0 || !warn_deprecated_decl)
     return;

+  if (current_function_decl && TREE_DEPRECATED (current_function_decl))
+    return;
+
   if (DECL_P (node))
     {
       expanded_location xloc = expand_location (DECL_SOURCE_LOCATION (node));

(Available under GPLv2 or later)

You may wish to adapt this patch to a later version of GCC (perhaps no changes are needed, perhaps major changes are needed), and build GCC from source with this patch applied. Or you may report this as a feature request on FSF GCC bugzilla.

  • Neat! That's a pretty good answer. I think I'm going to make this a feature request. Where did you find the diff? – Magnus Hoff Nov 20 '12 at 15:24
  • 1
    Download FSF sources, download Apple sources, unpack both side by side, run a recursive diff, search for "deprecated" in the results and hope there aren't too many results :) –  Nov 20 '12 at 15:28
  • Hehe, got it. I will have to schedule time for that... :) Thanks! – Magnus Hoff Nov 20 '12 at 15:30
  • @MagnusHoff Just curious if you ever filed that feature request. A link would make a very handy addition to this answer. – David Z Apr 03 '20 at 02:18
  • @DavidZ, sorry, no. It quickly became irrelevant to me so I never found the time to do it. – Magnus Hoff Apr 03 '20 at 10:30
0

I encounter the same issue. The solution that came up is the following

typedef OLD_A_NOT_TO_BE_USED a __attribute__((deprecated));

int OLD_A_NOT_TO_BE_USED () {
    return 10;
}

int __attribute__((deprecated)) b() {
    return OLD_A_NOT_TO_BE_USED () * 2; //< I want to get rid of warnings from this line
}

int main() {
    return b(); //< I expect a warning on this line only
}

So I just rename my a class into OLD_A_NOT_TO_BE_USED class. I get the warning only on return b(); and if someone was using a they will still get the deprecated warning.

wincrasher
  • 121
  • 1
  • 10
  • Maybe something changed since 2015, but this doesn't work now (with g++ 12.2): `error: 'OLD_A_NOT_TO_BE_USED' does not name a type` – Mark Gates May 23 '23 at 04:45