Aviso do Compilador (nível 3) C4839
uso não padrão da classe 'type' como um argumento para uma função variádica
Classes ou structs que são passadas para uma função variádica como printf
devem ser facilmente copiáveis. Ao passar esses objetos, o compilador simplesmente faz uma cópia bit a bit e não chama o construtor nem o destruidor.
Esse aviso está disponível no Visual Studio 2017 e posteriores.
Exemplo
A amostra a seguir gera 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
}
Para corrigir o erro, é possível chamar uma função membro que retorna um tipo facilmente copiado,
std::atomic<int> i(0);
printf("%i\n", i.load());
Para cadeias de caracteres criadas e gerenciadas usando o CStringW
, o operator LPCWSTR()
fornecido deve ser usado para converter um objeto CStringW
no ponteiro do C esperado pela cadeia de caracteres de formato.
CStringW str1;
CStringW str2;
// ...
str1.Format("%s", static_cast<LPCWSTR>(str2));