如果调用某些函数,是否可以强制编译错误?

时间:2012-05-23 20:33:47

标签: c++ visual-studio-2010 visual-c++ compiler-errors compiler-warnings

我有我的软件的v1和v2版本。 v1使用注册表来保存设置,大量调用GetProfileInt等.v2现在使用sqlite db来保存设置。

我们目前正在开发两个分支,并且正在将v1的新功能合并到v2分支。我们当前必须记住更新任何注册表调用以使用新的配置数据库,这已经错过了几次。

如果在v2中使用了任何GetProfile ...或WriteProfile ...函数,我想要抛出编译器错误。

我们在Visual Studio 2010中使用C ++。如果没有内置任何内容,我可以使用脚本的输出以某种方式抛出编译器错误吗?

6 个答案:

答案 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文件,你可以添加这样的内容(适当时使用WA)。这至少会导致链接器错误(编译器警告/错误将取决于标志):

#define GetProfileIntA InvalidFunctionDoNotCallMe

Windows已将GetProfileInt等函数定义为A或W版本的宏。

答案 3 :(得分:1)

接受的答案是将这些功能标记为已弃用,但这并不符合问题的要求,原因有两个:

  • 它只发出警告,而不是错误。
  • 即使您使用的是v1代码,它也会发出警告。

有充分的理由想要这个,但实际上并不是原始问题所要求的。

幸运的是,有一种非常简单的方法可以解决问题所要求的问题。如果函数根本不存在,编译器将始终抛出错误。只需将函数放在#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的信息。