Warning on Deprecated Functionality

Here's the question. Is there any way to add a compiler warning to code such that it is only activated when a function is called?

I have created a code generation tool that generates C++ classes. As I add features, I am considering moving some functionality from the main generated class to a new generated helper class. I would like to print out a "This function call is deprectated -- Please use the helper class" compiler warning message if the user's code calls a deprecated function.


An example of what I am trying to do:

The original Generated class header and source code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#ifndef Generated_h
#define Generated_h

#include <iosfwd>

class Generated
{
public:
	Generated(int a = 10) : value(a) {}
	int getValue() const { return value; }
	
	void foo(std::ostream& outfile);

private:
	int value;
};

#endif  /* Generated_h */ 


1
2
3
4
5
6
7
#include "Generated.h"
#include <iostream>

void Generated::foo(std::ostream& outfile)
{
	outfile << "The value is " << value << std::endl;
}


End-user's code (not generated--not under my control):

1
2
3
4
5
6
7
8
#include "Generated.h"
#include <iostream>

int main()
{
	Generated mc(5);
	mc.foo(std::cout);
}



After I add the helper class, I want something like this:

Generated class header and source

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#ifndef Generated_h
#define Generated_h

#include <iosfwd>

class Generated
{
public:
	Generated(int a = 10) : value(a) {}
	int getValue() const { return value; }
	
	// I am deprecating this function.
	// I would like to warn if it is called.
	void foo(std::ostream& outfile);

private:
	int value;
};

#endif  /* Generated_h */ 


1
2
3
4
5
6
7
8
9
10
11
12
#include "Generated.h"
#include "Helper_Generated.h"
#include <iostream>

// I am deprecating this function.
// I would like to warn if it is called.
void Generated::foo(std::ostream& outfile)
{
	// Until the function is removed, call the
	// functionality in the new class.
	Helper_Generated(*this).foo(outfile);
}


New generated helper class header and source

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#ifndef Helper_Generated_h
#define Helper_Generated_h

#include "Generated.h"
#include <iosfwd>

class Helper_Generated
{
public:
	Helper_Generated(const Generated& gen) : gen(gen) {}
	void foo(std::ostream& outfile);

private:
	const Generated& gen;
};

#endif /* Helper_Generated_h */ 


1
2
3
4
5
6
7
#include "Helper_Generated.h"
#include <iostream>

void Helper_Generated::foo(std::ostream& outfile)
{
	outfile << "The value is " << gen.getValue() << std::endl;
}



I want the following behavior based on the end-user's code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#include "Generated.h"
#include "Helper_Generated.h"
#include <iostream>

int main()
{
	Generated mc(5);

	// Warn if the user makes this call
	mc.foo(std::cout);

	// Don't warn if the user makes this call
	Helper_Generated(mc).foo(std::cout);
}

C++14 or later supports the attribute deprecated
http://en.cppreference.com/w/cpp/language/attributes

Typical usage:
1
2
3
4
5
6
7
8
9
10
struct A 
{
    [[ deprecated( "please use the helper class" ) ]] void foo() const {}
};

int main() 
{ 
    A a ;
    a.foo() ; 
}

http://coliru.stacked-crooked.com/a/b45e4595f6576dc4
Thanks @JLBorges. That's exactly what I'm looking for.

One of the projects that is using my tool is using C++11 and has no plans to switch any time soon. Is there a C++11 way to create the warning? (I know this is a long shot--just throwing the question out there.)

If there is no way in C++11, I will probably add an option to the tool to just drop the deprecated function from the generated code and force the users to use the new API right away.

You could use a macro that expands to the [[deprecated]] attribute when compiled in C++14 and falls back to the equivalent non-standard feature depending on the compiler.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#if __cplusplus >= 201402L
#define DEPRECATED(msg) [[ deprecated(msg) ]]
#elif defined(__GNUC__)
#define DEPRECATED(msg) __attribute__ ((deprecated(msg)))
#elif defined(_MSC_VER)
#define DEPRECATED(msg) __declspec(deprecated(msg))
#else
#define DEPRECATED(msg) 
#endif

struct A 
{
    DEPRECATED("please use the helper class") void foo() const {}
};

Last edited on
With Visual Studio you could use #pragma message("Deprecated")

With GCC #warning "Deprecated"
Thank-you @Peter87. That looks like what I want.

Topic archived. No new replies allowed.