只能由其他开发人员函数调用的C++开发人员函数

C++ Developer functions that can only be called by other developer functions

本文关键字:开发 C++ 函数 函数调用 其他      更新时间:2023-10-16

我们有许多函数对开发和测试非常有用,但不应该成为任何生产代码的一部分,主要是出于性能原因。我们的目标是让编译器确保标记为DEV_ONLY的函数只能由具有相同标记的函数调用。

我该如何实现以下内容:

virtual int foo() DEV_ONLY;
int bar() {
  foo(); // fails
}
int blah() DEV_ONLY {
  foo(); // works
}

DEV_ONLY是宏还是其他什么?

到目前为止,已经提出了以下想法,但并不完全是我想要的:

  • 易失性:我发现的一个选择是将它们标记为"易失性"(参见多布斯博士(,但我有两个问题。首先,它会滥用具有不同语义的说明符,这可能会在未来引发问题。其次,编译器关于函数"易失性"的警告没有那么大帮助。

  • friend:根据我的理解,这需要在实现这样一个方法的类中声明友谊。由于事先不知道使用该方法的测试或开发工具,所以我不是朋友解决方案的朋友。

  • 不导出:可能使用也可能不使用该方法的代码甚至可能在同一个类中。

  • 在Release构建中用noop替换:测试可能仍然需要Release模式中的那些方法。

#ifdef预处理器指令应该是实现两个目标的最直接的方法:

  • 不属于任何生产代码
  • 确保只能从具有相同"标记"的函数中调用它们(如果它们不存在,则未定义DEV_only的构建将不会编译(

这意味着要包装函数体以及相应的调用。

至于在发布版本中应该可用的测试方法:那么它们不是DEV_ONLY,不应该标记为DEV_ONLY。

处理此问题的一种方法是使用一个构建系统,该系统允许您将库定义为仅测试库,并限制生产二进制文件使用它们。例如,bazel提供了testonly选项(http://bazel.io/docs/be/common-definitions.html#common.testonly)

然后将代码组织到主二进制/库、仅测试库和测试代码中。这会给你一些类似的东西:cc_library(name="foo",srcs=["foo.cc"],hdrs=["foo.h"],)

cc_library(
  name = "test-utils",
  srcs = ["test-utils.cc"],
  hdrs = ["test-utils.h"],
  testonly = 1,
)
cc_test(
  ...
  deps = ["foo", "test-utils"],  # works
)
cc_libaray(
  ...
  deps = [..., "test-utils"],  # fails
)
cc_binary(
  ...
  deps = ["test-utils"],  # fails
)