/clr Restrições

Observe as seguintes restrições sobre o uso de /clr:

  • Em um manipulador de exceção estruturado, há restrições sobre o uso de _alloca durante a compilação com /clr. Para obter mais informações, consulte _alloca.

  • O uso de verificações de erro em tempo de execução não é válido com /clr. Para saber mais, confira Como usar verificações de tempo de execução nativas.

  • Quando /clr é usado para compilar um programa que usa apenas a sintaxe C++ padrão, as seguintes diretrizes se aplicam ao uso do assembly embutido:

    • O código de assembly embutido que pressupõe conhecimento sobre o layout empilhado nativo, as convenções de chamada fora da função atual ou outras informações de nível inferior sobre o computador poderá falhar se esse conhecimento for aplicado ao registro de ativação de uma função gerenciada. As funções que contêm o código de assembly embutido são geradas como funções não gerenciadas, como se fossem colocadas em um módulo separado compilado sem /clr.

    • Não há suporte para o código de assembly embutido em funções que passam parâmetros de função construídos por cópia.

  • As Funções vprintf não podem ser chamadas de um programa compilado com /clr.

  • O modificador naked__declspec é ignorado em /clr.

  • A função de conversão definida por _set_se_translator afetará somente as capturas no código não gerenciado. Para saber mais, confira Tratamento de exceção.

  • A comparação de ponteiros de função não é permitida em /clr.

  • O uso de funções que não são totalmente prototipadas não é permitido em /clr.

  • Não há suporte para as seguintes opções do compilador com /clr:

  • Não há suporte para a combinação da definição de pré-processador _STATIC_CPPLIB (/D_STATIC_CPPLIB) e a opção do compilador /clr. Isso ocorre porque a definição faz com que o aplicativo seja vinculado à Biblioteca Padrão C++ estática multi-threaded, para a qual não há suporte. Para obter mais informações, consulte /MD, /MT, /LD (Usar Biblioteca de Runtime).

  • Quando você usa /Zi com /clr, há implicações de desempenho. Para obter mais informações, consulte /Zi.

  • Passar um caractere largo para uma rotina de saída do .NET Framework sem especificar também /Zc:wchar_t ou sem converter o caractere em _wchar_t fará com que a saída seja exibida como um unsigned short int. Por exemplo:

    Console::WriteLine(L' ')              // Will output 32.
    Console::WriteLine((__wchar_t)L' ')   // Will output a space.
    
  • /GS é ignorado na compilação com /clr, a menos que uma função esteja sob o #pragma unmanaged ou se a função precisar ser compilada como código nativo, caso em que o compilador gerará o aviso C4793, que está desativado por padrão.

  • Confira /ENTRY para obter os requisitos de assinatura de função de um aplicativo gerenciado.

  • Os aplicativos compilados com /openmp e /clr só podem ser executados em um único processo do AppDomain. Para mais informações, confira /openmp (Ativar Suporte para OpenMP 2.0).

  • As funções que usam um número variável de argumentos (varargs) serão geradas como funções nativas. Será realizado o marshaling dos tipos de dados gerenciados na posição de argumento variável para tipos nativos. Qualquer tipo System.String é, na verdade, cadeias de caracteres largos, mas é realizado o marshaling dele para cadeias de caracteres de byte único. Portanto, se um especificador printf é %S (wchar_t*), será realizado o marshal para uma cadeia de caracteres %s em vez disso.

  • Ao usar a macro va_arg, você poderá obter resultados inesperados na compilação com /clr:pure. Para mais informações, confira va_arg, va_copy, va_end, va_start. As opções /clr:pure e /clr:safe do compilador foram preteridas no Visual Studio 2015 e estão sem suporte no Visual Studio 2017 e posteriores. O código que precisa ser "puro" ou "seguro" deve ser portado para o C#.

  • Você não deve chamar nenhuma função que ande na pilha para obter informações de parâmetro (argumentos de função) do código gerenciado. A camada P/Invoke faz com que essas informações fiquem mais abaixo na pilha. Por exemplo, não compile proxy/stub com /clr.

  • As funções serão compiladas em código gerenciado sempre que possível, mas nem todos os constructos C++ podem ser convertidos em código gerenciado. Essa determinação é feita por função. Se qualquer parte de uma função não puder ser convertida em código gerenciado, a função inteira será convertida em código nativo. Os casos a seguir impedem o compilador de gerar um código gerenciado.

    • Conversões geradas pelo compilador ou funções auxiliares. Conversões nativas são geradas para qualquer chamada de função por meio de um ponteiro de função, incluindo chamadas de função virtual.

    • Funções que chamam setjmp ou longjmp.

    • Funções que usam algumas rotinas intrínsecas para manipular diretamente os recursos do computador. Por exemplo, o uso de __enable e __disable, _ReturnAddress e _AddressOfReturnAddress ou todos os intrínsecos de multimídia resultarão em código nativo.

    • Funções que seguem a diretiva #pragma unmanaged. (O inverso, #pragma managed, também é permitido.)

    • Uma função que contém referências a tipos alinhados, ou seja, tipos declarados usando __declspec(align(...)).

Confira também