다음을 통해 공유


안전하지 않은 코드 구문에서 오류 및 경고 해결

이 문서에서는 다음 컴파일러 오류를 다룹니다.

  • CS0193: * 또는 -> 연산자를 데이터 포인터에 적용해야 합니다.
  • CS0196: 포인터는 하나의 값으로만 인덱싱되어야 합니다.
  • CS0208: 관리되는 형식('type')에 대한 포인터의 주소를 사용하거나, 크기를 얻거나, 선언할 수 없습니다.
  • CS0209: 고정 문에 선언된 로컬 형식은 포인터 형식이어야 합니다.
  • CS0210: 고정 또는 using 문 선언에 이니셜라이저를 제공해야 합니다.
  • CS0211: 지정된 식의 주소를 사용할 수 없습니다.
  • CS0212: 고정문 초기화식 내에서만 고정되지 않은 식의 주소를 가져올 수 있습니다.
  • CS0213: 고정 문을 사용하여 이미 고정된 식의 주소를 가져올 수 없습니다.
  • CS0214: 포인터 및 고정 크기 버퍼는 안전하지 않은 컨텍스트에서만 사용할 수 있습니다.
  • CS0227: 안전하지 않은 코드는 /unsafe로 컴파일하는 경우에만 표시할 수 있습니다.
  • CS0233: 'identifier'에 미리 정의된 크기가 없으므로 sizeof는 안전하지 않은 컨텍스트에서만 사용할 수 있습니다.
  • CS0242: 해당 작업이 void 포인터에 정의되지 않음
  • CS0244: 포인터 형식에서 'is' 또는 'as'가 모두 유효하지 않습니다.
  • CS0254: 고정문 할당의 오른쪽에는 캐스트 식이 올 수 없습니다.
  • CS0459: 읽기 전용 지역 변수의 주소를 사용할 수 없습니다.
  • CS0821: 암시적으로 형식화된 로컬은 수정할 수 없습니다.
  • CS1641: 고정 크기 버퍼 필드에는 필드 이름 다음에 배열 크기 지정자가 있어야 합니다.
  • CS1642: 고정 크기 버퍼 필드는 구조체의 멤버일 수 있습니다.
  • CS1656: '읽기 전용 변수 형식'이므로 'variable'에 할당할 수 없습니다.
  • CS1663: 고정 크기 버퍼 유형은 다음 boolbyteshortintlongcharsbyteushortuintulongfloatdouble중 하나여야 합니다.
  • CS1665: 고정 크기 버퍼의 길이가 0보다 커야 합니다.
  • CS1666: 고정되지 않은 식에 포함된 고정 크기 버퍼는 사용할 수 없습니다. 고정 문을 사용하는 것을 고려해 보세요.
  • CS1708: 고정 크기 버퍼는 로컬 또는 필드를 통해서만 액세스할 수 있습니다.
  • CS1716: 'System.Runtime.CompilerServices.FixedBuffer' 특성을 사용하지 마세요. 대신 '고정' 필드 한정자를 사용합니다.
  • CS1919: 안전하지 않은 형식 'type name'은 개체를 만드는 데 사용할 수 없습니다.
  • CS4004: 안전하지 않은 컨텍스트에서 사용할 수 없음 await
  • CS8812: 그룹을 함수가 아닌 포인터 형식으로 변환 &Method 할 수 없습니다.
  • CS9049: 고정 필드는 참조 필드가 아니어야 합니다.
  • CS9123: '&' 연산자는 비동기 메서드의 매개 변수 또는 지역 변수에 사용하면 안 됩니다.

포인터 작업 및 역참조

  • CS0193: * 데이터 포인터에 또는 -> 연산자를 적용해야 합니다.
  • CS0196: 포인터는 하나의 값으로만 인덱싱되어야 합니다.
  • CS0242: 해당 작업이 void 포인터에 정의되지 않음

포인터 작업을 올바르게 사용하려면 역참조, 인덱싱 및 산술 연산에 대한 규칙을 따릅니다. 자세한 내용은 포인터 형식함수 포인터를 참조하세요.

  • 데이터 포인터에 * 만 또는 -> 연산자를 적용합니다(CS0193). 비점수 형식 또는 함수 포인터에는 이러한 연산자를 사용하지 마세요. C/C++와 달리 C#에서는 함수 포인터를 역참조할 수 없습니다.
  • 값이 하나만 있는 인덱스 포인터(CS0196)입니다. 다차원 인덱싱은 포인터에서 지원되지 않습니다.
  • void 포인터(CS0242)에 정의되지 않은 작업을 방지합니다. 예를 들어 컴파일러가 가리키는 데이터의 크기를 모르기 때문에 void 포인터를 증가하지 마세요.

포인터 형식 및 관리되는 형식

  • CS0208: 관리되는 형식('type')에 대한 포인터의 주소를 사용하거나, 크기를 얻거나, 선언할 수 없습니다.
  • CS0233: 'identifier'에 미리 정의된 크기가 없으므로 sizeof는 안전하지 않은 컨텍스트에서만 사용할 수 있습니다.

포인터 및 연산자를 sizeof 올바르게 사용하려면 관리되지 않는 형식과 적절한 컨텍스트를 사용합니다. 자세한 내용은 관리되지 않는 형식연산자를sizeof 참조하세요.

  • 관리되지 않는 형식(CS0208)에서만 포인터를 사용합니다. 관리되는 형식의 주소를 얻거나, 크기를 구하거나, 포인터를 선언하지 마세요. 관리되는 형식에는 참조 형식 필드 또는 속성이 포함된 참조 형식 및 구조체가 포함됩니다.
  • 크기가 sizeof 컴파일 시간 상수가 아닌 형식(unsafe)으로 작업할 때 컨텍스트 내에서 연산자를 사용합니다.

고정 버퍼

  • CS0209: 고정 문에 선언된 로컬 형식은 포인터 형식이어야 합니다.
  • CS0210: 고정 또는 using 문 선언에 이니셜라이저를 제공해야 합니다.
  • CS0211: 지정된 식의 주소를 사용할 수 없습니다.
  • CS0212: 고정 문 이니셜라이저 내에서만 고정되지 않은 식의 주소를 사용할 수 있습니다.
  • CS0213: 고정 문을 사용하여 이미 고정된 식의 주소를 가져올 수 없습니다.
  • CS0254: 고정문 할당문의 오른쪽에 캐스트 표현식을 사용할 수 없습니다.
  • CS0459: 읽기 전용 지역 변수의 주소를 사용할 수 없습니다.
  • CS0821: 암시적으로 형식화된 로컬은 수정할 수 없습니다.
  • CS1656: '읽기 전용 변수 형식'이므로 'variable'에 할당할 수 없습니다.

이러한 오류는 문을 잘못 사용할 fixed 때 발생합니다. 이 문은 fixed 가비지 수집기가 이동 가능한 변수를 재배치하지 못하도록 하고 해당 변수에 대한 포인터를 선언합니다. 자세한 내용은 안전하지 않은 코드 및 포인터를 참조하세요.

fixed 문을 올바르게 사용하려면 다음과 같이 합니다.

  • 변수를 포인터 형식으로 선언합니다(CS0209).
  • 문(CS0210) 선언에 이니셜라이저를 제공합니다.
  • 필드, 지역 변수 및 포인터 간접 참조(CS0211)와 같은 유효한 식의 주소만 사용합니다. 두 변수의 합계와 같은 계산 식의 주소를 사용하지 마세요.
  • 명령문 이니셜라이저(fixed) 내에서만 고정되지 않은 식에서 address-of 연산자를 사용합니다.
  • 이미 고정된 fixed 식(CS0213)에는 구문을 사용하지 마십시오. 메서드의 지역 변수 및 매개 변수 unsafe 는 스택에 이미 고정되어 있습니다.
  • fixed 문 할당의 오른쪽에 캐스트 식을 사용하지 마세요 (CS0254).
  • 읽기 전용 지역 변수(CS0459)의 주소를 사용하지 마세요. foreach 루프, using 문 및 fixed 문의 변수는 읽기 전용입니다.
  • 명시적 형식을 사용하십시오 var 대신 fixed 문에서 (CS0821).
  • 루프, foreach 문 또는 using 문(fixed)과 같은 읽기 전용 컨텍스트의 변수에 할당하지 마세요.

안전하지 않은 컨텍스트 제한

  • CS0214: 포인터 및 고정 크기 버퍼는 안전하지 않은 컨텍스트에서만 사용할 수 있습니다.
  • CS0227: 안전하지 않은 코드는 /unsafe로 컴파일하는 경우에만 표시할 수 있습니다.
  • CS0244: 포인터 형식에서 'is' 또는 'as'가 모두 유효하지 않습니다.
  • CS1919: 안전하지 않은 형식 'type name'은 개체를 만드는 데 사용할 수 없습니다.
  • CS4004: 안전하지 않은 컨텍스트에서 대기할 수 없음
  • CS9123: '&' 연산자는 비동기 메서드의 매개 변수 또는 지역 변수에 사용하면 안 됩니다.

이러한 오류는 안전하지 않은 적절한 컨텍스트 없이 안전하지 않은 코드 구문을 사용하거나 안전하지 않은 코드에서 허용되지 않는 작업을 시도할 때 발생합니다. 자세한 내용은 안전하지 않은 코드 및 포인터 및키워드를unsafe 참조하세요.

안전하지 않은 코드를 올바르게 사용하려면 다음을 수행합니다.

  • 키워드(unsafe)를 사용하여 포인터 또는 고정 크기 버퍼를 사용하는 메서드, 형식 또는 코드 블록을 표시합니다.
  • 키워드를 사용할 때 프로젝트 설정에서 AllowUnsafeBlocks 컴파일러 옵션을 사용하도록 unsafe 설정합니다(CS0227).
  • 포인터 형식에는 is 또는 as 연산자를 사용하지 마세요 (CS0244). 이러한 형식 테스트 연산자는 포인터에 유효하지 않습니다.
  • 연산자를 new 사용하여 포인터 형식 인스턴스를 만들지 마세요(CS1919). 관리되지 않는 메모리에 개체를 만들려면 interop을 사용하여 포인터를 반환하는 네이티브 메서드를 호출합니다.
  • 안전하지 않은 코드를 비동기 코드와 별도로 유지합니다(CS4004). 안전하지 않은 작업에 대해 별도의 메서드를 만들고 비동기 메서드에서 호출합니다.
  • 비동기 메서드(&CS9123)의 매개 변수 또는 지역 변수에는 address-of 연산자()를 사용하지 마세요. 비동기 작업이 완료되면 변수가 없을 수 있습니다.

고정 크기 버퍼

  • CS1641: 고정 크기 버퍼 필드에는 필드 이름 다음에 배열 크기 지정자가 있어야 합니다.
  • CS1642: 고정 크기 버퍼 필드는 구조체의 멤버일 수 있습니다.
  • CS1663: 고정 크기 버퍼 유형은 bool, byte, short, int, long, char, sbyte, ushort, uint, ulong, float 또는 double 중 하나여야 합니다.
  • CS1665: 고정 크기 버퍼의 길이가 0보다 커야 합니다.
  • CS1666: 고정되지 않은 식에 포함된 고정 크기 버퍼는 사용할 수 없습니다. 고정 문을 사용해 보십시오
  • CS1708: 고정 크기 버퍼는 로컬 또는 필드를 통해서만 액세스할 수 있습니다.
  • CS1716: 'System.Runtime.CompilerServices.FixedBuffer' 특성을 사용하지 마세요. 대신 '고정' 필드 한정자를 사용합니다.
  • CS9049: 고정 필드는 ref 필드가 아니어야 합니다.

이러한 오류는 고정 크기 버퍼를 사용할 때 발생합니다. 고정 크기 버퍼는 구조체에 직접 포함된 배열이며 주로 interop 시나리오에 사용됩니다. 자세한 내용은 고정 크기 버퍼를 참조하세요.

고정 크기 버퍼를 올바르게 선언하고 사용하려면 다음을 수행합니다.

  • 양의 정수 상수(CS1641, CS1665)를 사용하여 필드 이름 뒤의 배열 크기를 지정합니다.
  • 클래스(CS1642)가 아닌 구조체에서만 고정 크기 버퍼를 선언합니다. 클래스에 필드가 필요한 경우 일반 배열을 사용합니다.
  • 지원되는 요소 형식bool, 즉 , ,byte, short, intlong, charsbyte, ushortuint, ulongfloat또는 double (CS1663) 중 하나를 사용합니다.
  • fixed 문을 적용하여 버퍼에 액세스하기 전에 구조체를 고정합니다(CS1666).
  • 중간 식(CS1708)이 아닌 로컬 또는 필드를 통해서만 고정 크기 버퍼에 액세스합니다.
  • fixed 특성(System.Runtime.CompilerServices.FixedBuffer) 대신 필드 한정자를 사용합니다.
  • 고정 크기 버퍼를 필드로 ref 선언하지 마세요(CS9049). 고정 크기 버퍼는 값 필드여야 합니다.

함수 포인터

  • CS8812: 그룹을 비 함수 포인터 형식으로 변환 &Method 할 수 없음

함수 포인터를 얻으려면 명시적 함수 포인터 형식 캐스트와 함께 address-of 연산자를 사용합니다. 주소 연산 & 자를 사용하여 메서드 그룹을 함수가 아닌 다른 포인터 형식에 void* 할당하지 마세요. 자세한 내용은 함수 포인터를 참조하세요.