C++ 在编译时根据printf格式检查参数的可移植方法,C++;

C++ 在编译时根据printf格式检查参数的可移植方法,C++;,c++,c++11,C++,C++11,我有一个日志函数my_log(const char*my_fmt,…)执行自定义日志记录。我希望my_log遵循Cprintf惯例。为了省去我的麻烦,我想警告用户printf()将给出的任何警告和错误。我需要的printf功能是-Wformat警告。当然还有错误 问题:如何在没有任何运行时开销的情况下实现这一点?(不使用特定于编译器的功能) 在GCC中,我可以使用\uuuuuuu属性((format()) void __attribute__((format(printf,1,2))) my_l

我有一个日志函数
my_log(const char*my_fmt,…)
执行自定义日志记录。我希望
my_log
遵循C
printf
惯例。为了省去我的麻烦,我想警告用户
printf()
将给出的任何警告和错误。我需要的printf功能是
-Wformat
警告。当然还有错误

问题:如何在没有任何运行时开销的情况下实现这一点?(不使用特定于编译器的功能)

在GCC中,我可以使用
\uuuuuuu属性((format())

void __attribute__((format(printf,1,2))) my_log(const char* fmt, ...){ }

现在,我需要编译英特尔C++编译器(ICC)和GCC。如果我能在ICC中实现属性检查,那就太好了。如果有一个纯C++语言技巧在编译时做这样的检查,那将是非常棒的。 没有可移植的方法可以做到这一点。即使对于
printf
系列,该语言也允许编译器假定您知道自己在做什么,并编译您所编写的内容,尽管如果启用g++会提供有用的警告


<> P>因为你的项目是C++,为什么不使用C++习惯用法,使用<代码> Boo::格式< /C>()还是IO流?这样,您就可以获得类型安全性,甚至不必担心验证输入。

没有可移植的方法可以做到这一点

您可以使用可变模板在运行时检查参数,但它会减慢
my_log()

另外,您可以尝试以下解决方案,但是
my_log()
将不会遵循
printf
惯例

#include <iostream>

#include <initializer_list>
#include <sstream>

class UC
{
    static std::stringstream ss;
    std::string str;
    friend const char *Str(std::initializer_list<UC> data);
public:
    template <class T> UC(T param) : str((ss.str(""), ss << param, ss.str())) {}
};
std::stringstream UC::ss;

void my_log(std::initializer_list<UC> data)
{
    std::string in_str;
    for (auto it = data.begin(); it != data.end(); it++)
        ret += it->str;

    std::cout << in_str.c_str() << '\n'; // Or whatever you want to do with your string.
}


int main()
{
    my_log({"Hello", '!', 11});
}
#包括
#包括
#包括
UC级
{
静态std::stringstream-ss;
std::字符串str;
friend const char*Str(std::initializer_list data);
公众:
模板UC(T参数):str((ss.str(“”),ss-str;

std::cout正如其他答案所说,没有可移植/标准的方法来实现问题的要求。但是,英特尔C/C++编译器(icc和icpc)与GNU函数属性100%兼容。请参阅。当我声明
\uuuu属性时,icpc会发出-Wformat警告((format())C语言中,选择一种语言。在C++中,你可以把一个代码> > CONTXPRPR < /C>变量模板来检查类型匹配,但是为什么不首先做一些更安全的类型呢?在C中,你可能是运气不好的。考虑一下:在“调试”下编译时,定义<代码> MyyLoG(x)< /C> > <代码> MyLogLogyDebug。(sprintf(some_global_big_buffer,x))
或类似的东西,使用
sprintf
来获取参数检查,尽管不精确
my_log()
功能。如果您能够使用C++11,请参阅@chux:Good thinking上的示例代码。使用未计算的上下文,例如
sizeof(printf(…)你应该能够得到一个警告,需要一个“调试”的构建。你使用的是什么代码> Prtff < /C>格式化。作为一个例子,你使用位置参数吗?有高性能类型的检查<代码> Prtff < /Calp>你想考虑的格式。谢谢。马克。我不想做真正的日志记录。(字符串操作等),因为它非常慢。我只希望编译器在每次出现my_log()时验证参数,因为格式字符串和参数类型在编译时是已知的。