“转发”字符串文字 [英] "Forwarding" string literals

查看:105
本文介绍了“转发”字符串文字的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在处理一个带有可变参数宏的库,该宏可以像printf一样使用

I am dealing with a library that has a variadic macro meant to be used like printf

#define PRINTF_LIKE (FORMAT, ...) //Some statement expression

由于 PRINTF_LIKE 进行评估,以避免出现常见的 if 和悬而未决的 else 问题,因为这些宏具有多条语句,它是使用 gcc语句表达式实现的。但是,我需要使用intel编译器构建代码,该编译器不允许内部可破坏的实体语句表达式。这意味着我不能编写这样的代码:

Since PRINTF_LIKE was required to evaluate to something, and in order avoid the usual if and dangling else issue with macros having multiple statements, it was implemented using gcc's statement expressions. However, I need my code to build with the intel compiler, which doesn't allow destructible entities inside a statement expression. This means I can't write code like this:

PRINTF_LIKE("%s", getString().c_str());

其中 getString 返回 std :: string 。要解决此问题,我有一个简单的可变参数模板包装器。

where getString returns an std::string. To work around this, I have a simple variadic template wrapper.

template <typename ... Rest>
int callPrintfLike(const char* const format, Rest... rest)
{
 return PRINTF_LIKE(format, rest...);//warning: format string is not a string literal [-Wformat-nonliteral]
}

并像这样使用它:

callPrintfLike("%s", getString().c_str());//warning as shown in the above comment

这会触发clang和gcc的 -Wformat-nonliteral 警告。我有办法以某种方式转发字符串文字,并且仅当未使用字符串文字调用callPrintfLike时才触发此警告吗?

This trips up clang and gcc's -Wformat-nonliteral warning. Is there a way for me to somehow "forward" string-literalness and have this warning be triggered only when callPrintfLike is not called with a string literal?

EDIT:以下答案建议使用 __ attribute __((format))。但是,由于格式不起作用 。 c $ c>属性需要一个可变函数。

EDIT : One of the answers below suggested using __attribute__((format)). However, that doesn't work since the format attribute needs a variadic function.

推荐答案

我通过关闭该函数的警告来绕过它,但提供了另一个警告宏来调用它,并通过三元运算符的死枝在此处重新启用这些警告。

I hacked around it by turning warnings off for the function, but providing another macro to call it through and re-enabling those warnings here through a dead-branch of the ternary operator.

//Compiler specific pragmas to turn off the -Wformat-security and -Wformat-literal warnings go here

template <typename ... Rest>
int callPrintfLike(const char* const format, Rest... rest)
{
 return PRINTF_LIKE(format, rest...);
}

//Pop diagnostic pragmas

#define NEW_PRINTF_LIKE (FORMAT, ...) (true ? callPrintfLike(FORMAT, ##__VA_ARGS__) : printf(FORMAT, ##__VA_ARGS__))

NEW_PRINTF_LIKE printf(FORMAT,## __ VA_ARGS __)将永远不会执行。但是, printf 调用的编译时检查以及关于非文字 FORMAT 的警告和参数与格式不匹配的警告字符串仍将启用。

In NEW_PRINTF_LIKE, printf(FORMAT, ##__VA_ARGS__) will never get executed. However, the compile-time checking of the printf call and warnings about non-literal FORMAT and arguments not matching the format string will still be enabled.

这篇关于“转发”字符串文字的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆