编译器扩展deprecated

背景
当前的工作与SVN有关,今天使用SVN库编写了一个小程序,编译代码时发现编译器告警:“warning: 'svn_client_ls2' is deprecated (declared at”。
svn@linux-rwdx:~/objs/motadou> make
g++ webdav.cpp -o webdav -I/home/svn/apps/svn/include/subversion-1 -I/home/svn/apps/neon/include/neon -I/home/svn/apps/apr-util/include/apr-1 -I/home/svn/apps/apr/include/apr-1 -I/home/svn/apps/sqlite/include -I/home/svn/apps/ssl/include/openssl\
-L/home/svn/apps/svn/lib -lsvn_client-1 -lsvn_wc-1 -lsvn_fs-1 -lsvn_fs_fs-1 -lsvn_fs_util-1 -lsvn_ra-1 -lsvn_ra_neon-1 -lsvn_ra_local-1 -lsvn_repos-1 -lsvn_delta-1 -lsvn_diff-1 -lsvn_subr-1  -L/home/svn/apps/neon/lib -lneon -L/home/svn/apps/apr-util/lib -laprutil-1 -L/home/svn/apps/apr/lib -lapr-1 -pthread /home/svn/apps/sqlite/lib/libsqlite3.a -L/home/svn/apps/ssl/lib -lssl -lcrypto -lz

webdav.cpp: In function 'int svn_list(Handle&, const std::string&)':
webdav.cpp:120: warning: 'svn_client_ls2' is deprecated (declared at /home/svn/apps/svn/include/subversion-1/svn_client.h:4942)
webdav.cpp:120: warning: 'svn_client_ls2' is deprecated (declared at /home/svn/apps/svn/include/subversion-1/svn_client.h:4942)

于是查看“/home/svn/apps/svn/include/subversion-1/svn_client.h”文件中对函数svn_client_ls2的声明,发现该函数之前有这么一个宏定义“SVN_DEPRECATED”。继续跟踪下去,发现SVN_DEPRECATED是这样定义的:

#ifndef SVN_DEPRECATED
# if !defined(SWIGPERL) && !defined(SWIGPYTHON) && !defined(SWIGRUBY)
#  if defined(__GNUC__) && (__GNUC__ >= 4 || (__GNUC__==3 && __GNUC_MINOR__>=1))
#   define SVN_DEPRECATED __attribute__((deprecated))
#  elif defined(_MSC_VER) && _MSC_VER >= 1300
#   define SVN_DEPRECATED __declspec(deprecated)
#  else
#   define SVN_DEPRECATED
#  endif
# else
#  define SVN_DEPRECATED
# endif
#endif

很明显这个告警表明"svn_client_ls2"在程序中,某个接口已经有替代接口或者不推荐继续使用,所以在编译的时候给出报警提醒开发者注意。之所以可以在编译期给出报警,主要是使用了“__attribute__((deprecated))”特性,我在ARM网站上发现有这样一段提示:
可以使用 deprecated 变量属性声明不提倡使用的变量,而不会导致编译器发出任何警告或错误。但是,对 deprecated 变量的任何访问都会生成警告,但仍会进行编译。警告指出了使用和定义变量的位置。这有助于确定不提倡使用特定定义的原因。


使用该属性,我们可以在我们对外提供库中,提前向使用方预告接口的废止,让开发者尽早转向替代接口。对该编译器扩展申明的变量或者函数,我们要明白:

  • 如果该变量或者函数没有被第三方开发者使用,那么即使开发者使用了包含该函数的库去编译代码,也不会出现任何警告或者错误。
  • 如果开发者在代码中引用了被“__attribute__((deprecated))”声明的变量或者函数,那么编译器此时才会出现警告,来提示函数已经过期。

测试使用该属性
// 保存当前为:test.cpp
// 编译:g++ -o test test.cpp
// 运行:./test

#include <iostream>

__attribute__((deprecated)) void GetSystemInfo()
{
	std::cout << "test __attribute__((deprecated))" << std::endl;	
}

int main()
{
	GetSystemInfo();

	return 0;
}
我们编译下这个文件,看看是否在编译期提醒我们“GetSystemInfo”这个接口已经过期了。
编译时报警告:“test.cpp:10:16: warning: ‘void GetSystemInfo()’ is deprecated (declared at test.cpp:3) [-Wdeprecated-declarations]”,提醒我们代码文件中第10行调用的GetSystemInfo已经过期。即使提醒了我们函数已经过期,但我们使用过期函数仍然编译成功,也可成功运行。
原文地址:https://www.cnblogs.com/motadou/p/2566028.html