编译器警告(等级 3)C4839

将类“type”作为可变参数函数的参数的用法不规范

传递给可变参数函数(如 printf)的类或结构必须是可复制的。 传递此类对象时,编译器只是执行按位复制,不会调用构造函数或析构函数。

此警告从 Visual Studio 2017 开始可用。

示例

下面的示例生成 C4839:

// C4839.cpp
// compile by using: cl /EHsc /W3 C4839.cpp
#include <atomic>
#include <memory>
#include <stdio.h>

int main()
{
    std::atomic<int> i(0);
    printf("%i\n", i); // error C4839: non-standard use of class 'std::atomic<int>'
                        // as an argument to a variadic function
                        // note: the constructor and destructor will not be called;
                        // a bitwise copy of the class will be passed as the argument
                        // error C2280: 'std::atomic<int>::atomic(const std::atomic<int> &)':
                        // attempting to reference a deleted function
}

若要更正错误,可调用一种成员函数,该函数返回可完全复制的类型,

    std::atomic<int> i(0);
    printf("%i\n", i.load());

对于使用 CStringW 生成和管理的字符串,提供的 operator LPCWSTR() 应用于将 CStringW 对象强制转换为格式字符串所需的 C 指针。

    CStringW str1;
    CStringW str2;
    // ...
    str1.Format("%s", static_cast<LPCWSTR>(str2));