Compartilhar via


Resolver erros e avisos em constructos de código não seguros

Este artigo aborda os seguintes avisos do compilador:

  • CS0193: O operador * ou -> deve ser aplicado a um ponteiro de dados
  • CS0196: Um ponteiro deve ser indexado por apenas um valor
  • CS0208: Não é possível tomar o endereço de, obter o tamanho ou declarar um ponteiro para um tipo gerenciado ('tipo')
  • CS0209: O tipo de local declarado em uma instrução fixa deve ser um tipo de ponteiro
  • CS0210: Você deve fornecer um inicializador em uma declaração fixa ou using de instrução
  • CS0211: Não é possível usar o endereço da expressão fornecida
  • CS0212: Você só pode usar o endereço de uma expressão não fixa dentro de um inicializador de instrução fixa
  • CS0213: Você não pode usar a instrução fixed para obter o endereço de uma expressão já fixada
  • CS0214: ponteiros e buffers de tamanho fixo só podem ser usados em um contexto não seguro
  • CS0227: Código não seguro só poderá aparecer se compilar com /unsafe
  • CS0233: 'identifier' não tem um tamanho predefinido, portanto, sizeof só pode ser usado em um contexto não seguro
  • CS0242: A operação em questão é indefinida em ponteiros nulos
  • CS0244: 'is' nem 'as' é válido em tipos de ponteiro
  • CS0254: O lado direito de uma atribuição de instrução fixa pode não ser uma expressão de conversão
  • CS0459: Não é possível obter o endereço de uma variável local somente leitura
  • CS0821: variáveis locais tipadas implicitamente não podem ser declaradas como constantes
  • CS1641: um campo de buffer de tamanho fixo deve ter o especificador de tamanho da matriz após o nome do campo
  • CS1642: campos de buffer de tamanho fixo só podem ser membros de structs.
  • CS1656: Não é possível atribuir a 'variável' porque é um 'tipo de variável de leitura única'
  • CS1663: o tipo de buffer de tamanho fixo deve ser um dos seguintes: bool, , byte, short, int, long, char, sbyte, ushort, uint, , ulong, ou floatdouble
  • CS1665: buffers de tamanho fixo devem ter um comprimento maior que zero
  • CS1666: Você não pode usar buffers de tamanho fixo contidos em expressões não fixas. Tente usar a instrução fixa.
  • CS1708: Buffers de tamanho fixo só podem ser acessados por meio de locais ou campos
  • CS1716: não use o atributo 'System.Runtime.CompilerServices.FixedBuffer'. Em vez disso, use o modificador de campo 'fixo'.
  • CS1919: O tipo não seguro 'type name' não pode ser usado na criação de objeto.
  • CS4004: Não é possível await em um contexto não seguro
  • CS8812: Não é possível converter &Method grupo em tipo de ponteiro não funcional.
  • CS9123: o operador '&' não deve ser usado em parâmetros ou variáveis locais em métodos assíncronos.

Operações de ponteiro e desreferenciamento

  • CS0193: O operador * ou -> deve ser aplicado a um ponteiro de dados
  • CS0196: Um ponteiro deve ser indexado por apenas um valor
  • CS0242: A operação em questão é indefinida em ponteiros nulos

Para usar as operações de ponteiro corretamente, siga as regras para operações de desreferenciamento, indexação e aritmética. Para obter mais informações, consulte tipos de ponteiro e ponteiros de função.

  • Aplique o operador * ou -> somente aos ponteiros de dados (CS0193). Não use esses operadores com tipos que não são ponteiros ou ponteiros de função. Os ponteiros de função não podem ser desreferenciados em C#, ao contrário de C/C++.
  • Ponteiros de índice com apenas um valor (CS0196). Não há suporte para indexação multidimensional em ponteiros.
  • Evite operações indefinidas em ponteiros nulos (CS0242). Por exemplo, não incremente um ponteiro nulo porque o compilador não sabe o tamanho dos dados que estão sendo apontados.

Tipos de ponteiro e tipos gerenciados

  • CS0208: Não é possível obter o endereço de, o tamanho de, ou declarar um ponteiro para um tipo gerenciado ('type')
  • CS0233: 'identifier' não tem um tamanho predefinido, portanto, sizeof só pode ser usado em um contexto não seguro

Para trabalhar com ponteiros e o sizeof operador corretamente, use tipos não gerenciados e contextos adequados. Para obter mais informações, consulte tipos não gerenciados e o sizeof operador.

  • Use ponteiros somente com tipos não gerenciados (CS0208). Não obtenha o endereço de, obtenha o tamanho de, ou declare ponteiros para tipos gerenciados. Os tipos gerenciados incluem tipos de referência e structs que contêm campos de tipo de referência ou propriedades.
  • Use o sizeof operador em um unsafe contexto ao trabalhar com tipos cujo tamanho não é uma constante de tempo de compilação (CS0233).

Buffers fixos

  • CS0209: O tipo de local declarado em uma instrução fixa deve ser um tipo de ponteiro
  • CS0210: Você deve fornecer um inicializador em uma declaração fixa ou using de instrução
  • CS0211: Não é possível usar o endereço da expressão fornecida
  • CS0212: Você só pode usar o endereço de uma expressão não fixa dentro de um inicializador de instrução fixa
  • CS0213: Você não pode usar a instrução 'fixed' para tomar o endereço de uma expressão já fixada
  • CS0254: O lado direito de uma atribuição de instrução fixa pode não ser uma expressão de conversão
  • CS0459: Não é possível obter o endereço de uma variável local somente leitura
  • CS0821: Variáveis locais tipadas implicitamente não podem ser fixadas
  • CS1656: Não é possível atribuir a 'variável' porque é uma 'variável de tipo somente leitura'

Esses erros ocorrem quando você usa a fixed instrução incorretamente. A fixed instrução impede que o coletor de lixo realoque uma variável móvel e declara um ponteiro para essa variável. Para obter mais informações, consulte Código e ponteiros não seguros.

Para usar a instrução fixed corretamente:

  • Declare a variável como um tipo de ponteiro (CS0209).
  • Forneça um inicializador na declaração da instrução fixed (CS0210).
  • Use o endereço somente de expressões válidas: campos, variáveis locais e indireção de ponteiro (CS0211). Não tome o endereço de expressões calculadas, como a soma de duas variáveis.
  • Use o operador de endereço em expressões não fixadas somente dentro do fixed inicializador de instrução (CS0212).
  • Não use uma fixed instrução em expressões já resolvidas (CS0213). Variáveis locais e parâmetros em um método unsafe já estão fixadas na pilha.
  • Não use expressões de conversão no lado direito de uma atribuição de comando (CS0254).
  • Não use o endereço das variáveis locais somente leitura (CS0459). Variáveis em foreach loops, using instruções e fixed instruções são somente leitura.
  • Use tipos explícitos em vez de var instruções fixed (CS0821).
  • Não atribua variáveis em contextos somente leitura, como laços foreach, instruções using ou fixed (CS1656).

Restrições de contexto não seguras

  • CS0214: ponteiros e buffers de tamanho fixo só podem ser usados em um contexto não seguro
  • CS0227: Código não seguro só poderá aparecer se compilar com /unsafe
  • CS0244: 'is' nem 'as' são válidos em tipos de ponteiro
  • CS1919: O tipo não seguro 'type name' não pode ser usado na criação de objeto
  • CS4004: Não é possível aguardar em um contexto não seguro
  • CS9123: O operador '&' não deve ser usado em parâmetros ou variáveis locais em métodos assíncronos

Esses erros ocorrem quando você usa constructos de código não seguros sem o contexto não seguro adequado ou quando você tenta operações que não são permitidas em código não seguro. Para obter mais informações, consulte Código e ponteiros não seguros e a unsafe palavra-chave.

Para usar o código não seguro corretamente:

  • Marque métodos, tipos ou blocos de código que usam ponteiros ou buffers de tamanho fixo com a unsafe palavra-chave (CS0214).
  • Habilite a opção do compilador AllowUnsafeBlocks nas configurações do projeto ao usar a unsafe palavra-chave (CS0227).
  • Não use os operadores is ou as com tipos de ponteiro (CS0244). Esses operadores de teste de tipo não são válidos para ponteiros.
  • Não use o new operador para criar instâncias de tipo de ponteiro (CS1919). Para criar objetos na memória não gerenciada, use a interoperabilidade para chamar métodos nativos que retornam ponteiros.
  • Mantenha o código não seguro separado do código assíncrono (CS4004). Crie métodos separados para operações inseguras e chame-os a partir de métodos assíncronos.
  • Não use o operador de endereço (&) em parâmetros ou variáveis locais em métodos assíncronos (CS9123). A variável pode não existir quando a operação assíncrona for concluída.

Buffers de tamanho fixo

  • CS1641: um campo de buffer de tamanho fixo deve ter o especificador de tamanho da matriz após o nome do campo
  • CS1642: os campos de buffer de tamanho fixo só podem ser membros de structs
  • CS1663: O tipo de buffer de tamanho fixo deve ser um dos seguintes: bool, byte, short, int, long, char, sbyte, ushort, uint, ulong, float ou double
  • CS1665: buffers de tamanho fixo devem ter um comprimento maior que zero
  • CS1666: Você não pode usar buffers de tamanho fixo contidos em expressões não fixas. Tente usar a instrução fixa
  • CS1708: Buffers de tamanho fixo só podem ser acessados por meio de locais ou campos
  • CS1716: Não use o atributo 'System.Runtime.CompilerServices.FixedBuffer'. Em vez disso, use o modificador de campo 'fixo'

Esses erros ocorrem quando você trabalha com buffers de tamanho fixo. Os buffers de tamanho fixo são matrizes inseridas diretamente em structs e são usados principalmente para cenários de interoperabilidade. Para obter mais informações, consulte buffers de tamanho fixo.

Para declarar e usar buffers de tamanho fixo corretamente:

  • Especifique o tamanho da matriz após o nome do campo usando uma constante inteiro positiva (CS1641, CS1665).
  • Declare buffers de tamanho fixo somente em structs, não em classes (CS1642). Use uma matriz regular se precisar do campo em uma classe.
  • Use um dos tipos de elemento com suporte: bool, , byte, short, int, long, char, , sbyte, , ushort, uint, , ulong, , floatou double (CS1663).
  • Use uma fixed instrução para fixar o struct que contém antes de acessar o buffer (CS1666).
  • Acesse buffers de tamanho fixo apenas por meio de locais ou campos, não por meio de expressões intermediárias (CS1708).
  • Use o fixed modificador de campo em vez do System.Runtime.CompilerServices.FixedBuffer atributo (CS1716).

Ponteiros de função

  • CS8812: Não é possível converter &Method grupo em tipo de ponteiro não-função

Para obter um ponteiro de função, use o operador de endereço com uma conversão de tipo de ponteiro de função explícita. Não use o operador de endereço & para atribuir grupos de métodos a void* ou outros tipos de ponteiro que não sejam de função. Para obter mais informações, consulte Ponteiros de Função.