Поделиться через


Предупреждение компилятора (уровень 3) C4839

нестандартное использование класса "type" в качестве аргумента для функции variadic

Классы или структуры, передаваемые в вариативную функцию, например 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));