我有我的软件的v1和v2版本。 v1使用注册表来保存设置,大量调用GetProfileInt等.v2现在使用sqlite db来保存设置。
我们目前正在开发两个分支,并且正在将v1的新功能合并到v2分支。我们当前必须记住更新任何注册表调用以使用新的配置数据库,这已经错过了几次。
如果在v2中使用了任何GetProfile ...或WriteProfile ...函数,我想要抛出编译器错误。
我们在Visual Studio 2010中使用C ++。如果没有内置任何内容,我可以使用脚本的输出以某种方式抛出编译器错误吗?
答案 0 :(得分:12)
由于这个答案被接受,我不妨包括提问者实际使用的解决方案:
jacobsee发现了deprecated pragma
#pragma deprecated(GetProfileInt)
您可以使用__declspec(deprecated)
将其声明为已弃用。它看起来像这样:
UINT __declspec(deprecated) WINAPI GetProfileInt(
__in LPCTSTR lpAppName,
__in LPCTSTR lpKeyName,
__in INT nDefault
);
您必须从您关注的每个翻译单元中包含的标题中执行此操作。只要包含已弃用声明的翻译单元使用该功能,这样做会导致警告。
如果您想要编译错误,并且您的项目尚未将警告视为错误,那么您必须将其打开,并修复您忽略的所有警告。 (无论您是否使用此解决方案,这些都是很好的做法。)
答案 1 :(得分:3)
将我的评论推荐给答案:
您可以使用宏将它们重新定义为无法编译的内容:
#define GetProfile HAHA_Nice_try_This_will_not_compile!!!
要注意的是,您需要确保在代码之外没有(合法地)调用它。
(因此,您应该在所有包含之后放置宏。)
答案 2 :(得分:1)
如果你有一个常见的#include文件,你可以添加这样的内容(适当时使用W
或A
)。这至少会导致链接器错误(编译器警告/错误将取决于标志):
#define GetProfileIntA InvalidFunctionDoNotCallMe
Windows已将GetProfileInt
等函数定义为A或W版本的宏。
答案 3 :(得分:1)
接受的答案是将这些功能标记为已弃用,但这并不符合问题的要求,原因有两个:
有充分的理由想要这个,但实际上并不是原始问题所要求的。
幸运的是,有一种非常简单的方法可以解决问题所要求的问题。如果函数根本不存在,编译器将始终抛出错误。只需将函数放在#ifndef
。
#ifndef V2
void GetProfile()
{
// Get the profile
}
void WriteProfile()
{
// Write the profile
}
#endif
答案 4 :(得分:0)
我相信你可以在#define GetProfileInt(a, b, c) "don't use this";
#include
之后Windows.h
。
由于GetProfileInt
是用于路由到正确函数的宏,因此这将导致宏重新定义。由于无法将char[]
分配给UINT
,因此编译器error
为。{/ p>
这是一个肮脏,肮脏的黑客,但我觉得要洗澡讨论它。
答案 5 :(得分:0)
如果您可以随意将函数转换为模板,则可以执行以下操作:
template <typename...>
struct always_false { static constexpr bool value = false; };
template <typename... Ts>
void never_call_me(Ts&&...)
{
static_assert(always_false<Ts...>::value,
"You should have never called this function!");
}
这具有以下优点:编译错误将很干净+您可以提供错误消息。 Found here,请查看该答案,以获取更多有关为何有效以及为何需要always_false
的信息。