【问题标题】:Macro to raise compiler error for string literal C++用于引发字符串文字 C++ 的编译器错误的宏
【发布时间】:2018-03-02 22:43:31
【问题描述】:

我知道(邪恶?)C++ 宏会引发编译器错误,但字符串文字除外(前段时间在 SO 中找到但无法再次找到):

#define IS_STRING_LITERAL(X) "" X ""

是否有一个宏可以做'相反',即在字符串文字上引发编译器错误,但不会在其他输入上引发?

编辑:见评论,这是用于微控制器上的调试宏。字符串文字应该存在于闪存中,如果我调用了错误的宏,我希望在编译器时得到通知。 'Others' 应该是 int、float、char、char [] 和其他 'basic' 类型。

【问题讨论】:

  • 你为什么想要一个?
  • @HolyBlackCat 我想在 Arduino 上编写调试宏。调用字符串文字的宏将在 F 宏上使用 print 来不填充 SRAM(只有 2kB SRAM,如果为空,则要调试地狱;相比之下,更多的 Flash 可用)。如果我在字符串文字上调用了不带 F 的错误宏,我希望在编译时得到通知。
  • PS:我可能会想到一个宏在const char * 上调用未定义的模板函数,但这听起来有点复杂。
  • 其他宏的有效参数是什么?

标签: c++ macros


【解决方案1】:

取决于那些“其他输入”是什么。如果它们可以是任何东西,那么答案可能是“不可能的”。

你可以这样做:

#define foo(x) (std::enable_if_t<!std::is_same_v<const char *, decltype(+(x))>>(), (x))

这一行检查x 是否为const char *(或衰减为1),如果为真则引发错误。 (这不是您要求的:不可能将普通的 const char [] 传递给它。)

std::cout << foo(123); // Works.
std::cout << foo("123"); // error: no type named 'type' in 'struct std::enable_if<false, void>'

【讨论】:

  • 奇怪,我的 Visual Studio 没有显示任何错误。 decltype中的加号,它有什么作用?它迫使它做某事?
  • @Zebrafish + 强制数组到指针衰减。我的意思是我期待它。 :|
  • @HolyBlackCat 为什么你不只使用#define foo(x) decltype(x) var; 或#define foo(x) void* var=(decltype(x)) x; 这会检测到missing initializer 的错误,因为数组litterals 应该总是在声明后被初始化。
  • @Abra001 我认为 OP 希望宏在不是字符串文字时返回它的参数。并且您的宏将错误地触发任何 const 数组的错误。 (还要注意没有数组字面量,只有常量数组。)
  • 我希望后面有一些诡计,最后一个项目符号不是那么明显,使用 typeid(X).name() 检查它是否以“const char[”或“const”开头字符*”。如果是这样,请放弃断言。
猜你喜欢
  • 1970-01-01
  • 2019-05-10
  • 2016-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多