3

I have a widely used C99 library with multiple header files. I need to deprecate a specific header file. I'd like to create a compiler warning for users that this header file will be deprecated.

Ideally I'd like to use the diagnostic directive #warning

#warning "Warning this header file will be removed!"

However, this isn't part of the C standard until C23.

Before its standardization in C23, #warning has been provided by many compilers in all modes as a conforming extension. - cppreference

What's the best approach that will work on as much compilers as possible to create a warning for users?

jpr42
  • 718
  • 3
  • 14
  • 5
    As far as I know (I must confess I wasn't even aware that `#warning` was a non-standard compiler thing), `#warning` is your best shot. I mean, if there were another method, then compilers would have used it rather than inventing `#warning` (I mean non-microsoft one. Microsoft loves inventing non-standard things. But others usually do that when they have no other choice) Worst case scenario: instead of a warning, about `this header file will be removed`, the user would get a warning about `#warning "this header file will be removed"` not understood by compiler. Either case, message sent. – chrslg Jan 03 '23 at 16:43

1 Answers1

2

The simplest solution is to just use #warning anyway. As your quoted cppreference page says, compilers already have been using it for years before its official standardization in C23. And as chrslg pointed out, using it on a compiler that doesn't support it will produce an error for an unsupported preprocessing directive, which should be an adequate reminder for programmers to stop using the header file.

If you want a fully C89-compatible solution, you could do:

#ifndef IGNORE_DEPRECATION
    #error "This header will be removed in a future release.  Use MyNewHeader.h instead."
#endif

This will treat the warning as an error, unless the program using the obsolete header (or its Makefile flags) defines the IGNORE_DEPRECATION macro to allow the program to compile anyway.

Alternatively, you could tag all of the individual functions as deprecated. Before the deprecated attribute was standardized in C23, compilers had custom ways of doing this:

  • Microsoft Visual C++ uses __declspec(deprecated), or __declspec(deprecated("custom message")).
  • GCC uses __attribute__((deprecated)) or (in version 8.0 and higher) __attribute__((deprecated("custom message"))).

If you go this route, you will probably want to abstract these attributes behind macros (conditionally compiled based on _MSC_VER and __GNUC__ versions.

dan04
  • 87,747
  • 23
  • 163
  • 198