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

이 문서에서는 다음 컴파일러 진단에 대해 설명합니다.

  • CS0193: * 또는 -> 연산자를 포인터에 적용해야 합니다.
  • CS0196: 포인터는 하나의 값으로만 인덱싱되어야 합니다.
  • CS0208: 관리되는 형식('type')에 대한 포인터의 주소를 사용하거나, 크기를 얻거나, 선언할 수 없습니다.
  • CS0209: 문에 fixed 선언된 로컬의 형식은 포인터 형식이어야 합니다.
  • CS0210: fixed 또는 using 문 선언에 초기화 식을 제공해야 합니다.
  • CS0211: 지정된 식의 주소를 사용할 수 없습니다.
  • CS0212: 문 이니셜라이저 내에서만 고정되지 않은 식의 fixed 주소를 사용할 수 있습니다.
  • CS0213: 문을 사용하여 fixed 이미 고정된 식의 주소를 사용할 수 없습니다.
  • 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
  • CS7092: 고정 버퍼에는 하나의 차원만 있을 수 있습니다.
  • CS8372: 속성에 'System.Runtime.CompilerServices.FixedBuffer' 특성을 사용하지 마세요.
  • CS8812: > 메서드 그룹 'method'를 함수가 아닌 포인터 형식 'type'으로 변환할 수 없습니다.
  • CS9049: 고정 필드는 참조 필드가 아니어야 합니다.
  • CS9123: '&' 연산자는 비동기 메서드의 매개 변수 또는 지역 변수에 사용하면 안 됩니다.
  • CS9360: 이 작업은 안전하지 않은 컨텍스트에서만 사용할 수 있습니다.
  • CS9361: stackalloc 내부에 SkipLocalsInit 이니셜라이저가 없는 식은 안전하지 않은 컨텍스트에서만 사용할 수 있습니다.
  • CS9362: 'member'는 '' 또는 'RequiresUnsafeextern'로 표시되므로 안전하지 않은 컨텍스트에서 사용해야 합니다.
  • CS9363: 서명에 포인터가 있으므로 안전하지 않은 컨텍스트에서 'member'를 사용해야 합니다.
  • CS9364: 안전하지 않은 멤버 'member'는 안전한 멤버 'member'를 재정의할 수 없습니다.
  • CS9365: 안전하지 않은 멤버 'member'는 안전한 멤버 'member'를 암시적으로 구현할 수 없습니다.
  • CS9366: 안전하지 않은 멤버 'member'가 안전한 멤버 'member'를 구현할 수 없습니다.
  • CS9367: RequiresUnsafeAttribute 이 기호에 적용할 수 없습니다.
  • CS9368: RequiresUnsafeAttribute 업데이트된 메모리 안전 규칙에 따라만 유효합니다.
  • CS9376: 'RequiresUnsafe' 또는 'extern'로 표시된 생성자 '생성자'가 '제네릭 형식 또는 메서드'의 형식 매개 변수 'type 매개 변수'에 대한 'new()' 제약 조건을 만족하려면 안전하지 않은 컨텍스트가 필요합니다.
  • CS9377: 'unsafe' 한정자는 현재 메모리 안전 규칙에 따라 여기에 아무런 영향을 주지 않습니다.

포인터 작업 및 역참조

  • 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: 안전하지 않은 컨텍스트에서 사용할 수 없음 await
  • CS9123: '&' 연산자는 비동기 메서드의 매개 변수 또는 지역 변수에 사용하면 안 됩니다.
  • CS9360: 이 작업은 안전하지 않은 컨텍스트에서만 사용할 수 있습니다.
  • CS9361: stackalloc 내부에 SkipLocalsInit 이니셜라이저가 없는 식은 안전하지 않은 컨텍스트에서만 사용할 수 있습니다.
  • CS9362: 'member'는 '' 또는 'RequiresUnsafeextern'로 표시되므로 안전하지 않은 컨텍스트에서 사용해야 합니다.
  • CS9363: 서명에 포인터가 있으므로 안전하지 않은 컨텍스트에서 'member'를 사용해야 합니다.
  • CS9376: 생성자 '생성자'가 '제네릭 형식 또는 메서드'의 형식 매개 변수 'type 매개 변수'의 'new()' 제약 조건을 충족하려면 'RequiresUnsafe' 또는 'extern'로 표시되어야 하며, 이를 위해 안전하지 않은 컨텍스트가 필요합니다.

이러한 진단은 필수 unsafe 컨텍스트 없이 안전하지 않은 코드 구문을 사용하거나 안전하지 않은 형식으로 허용되지 않는 작업을 시도할 때 발생합니다. 자세한 내용은 안전하지 않은 코드와 포인터 및키워드를unsafe 참조하세요.

  • 키워드를 사용하여 포인터 또는 고정 크기 버퍼를 사용하는 메서드, 형식 또는 코드 블록을 표시합니다 unsafe (CS0214). 컴파일러는 포인터 형식 또는 고정 크기 버퍼 필드에서 작동하는 모든 코드에 대해 명시적 안전하지 않은 컨텍스트가 필요합니다.
  • 프로젝트 설정(CS0227)에서 AllowUnsafeBlocks 컴파일러 옵션을 사용하도록 설정합니다. 이 옵션을 사용하지 않으면 코드가 올바르더라도 컴파일러는 모든 unsafe 블록을 거부합니다.
  • 포인터 형식에는 is 또는 as 연산자를 사용하지 마세요 (CS0244). 포인터가 형식 계층 구조에 참여하지 않으므로 이러한 형식 테스트 연산자는 포인터에 유효하지 않습니다.
  • 연산자를 new 사용하여 포인터 형식 인스턴스를 만들지 마세요(CS1919). 관리되지 않는 메모리에 개체를 만들려면 interop을 사용하여 포인터를 반환하는 네이티브 메서드를 호출합니다.
  • 안전하지 않은 코드를 비동기 코드와 별도로 유지합니다(CS4004). 컴파일러는 런타임 동안 unsafe 블록 내에서 await 표현식을 허용하지 않습니다. 이는 실행 중단 지점에서 포인터의 유효성을 보장할 수 없기 때문입니다. 안전하지 않은 작업에 대해 별도의 메서드를 만들고 비동기 메서드에서 호출합니다.
  • 비동기 메서드(&CS9123)의 매개 변수 또는 지역 변수에는 address-of 연산자()를 사용하지 마세요. 일시 중단 지점 후에 비동기 작업이 다시 시작될 때 스택에 변수가 없을 수 있습니다.
  • 키워드 unsafe (sizeof)으로 포인터 역참조, 주소 지정 등과 같은 안전하지 않은 구문을 포함하는 관리되지 않는 형식을 사용하는 작업을 표시합니다. C# 15의 업데이트된 메모리 안전 규칙에 따라 컴파일러는 안전하지 않은 컨텍스트가 필요한 개별 작업을 식별합니다.
  • 초기화자가 없는 표현에 unsafe 키워드를 stackalloc로 사용하는 경우, SkipLocalsInit 속성이 적용됩니다(CS9361). 이니셜라이저가 없으면 스택 할당 메모리에 초기화되지 않은 데이터가 포함되며 이는 안전하지 않은 작업입니다.
  • 또는 로 표시된 멤버, (CS9362) 또는 포인터가 포함된 서명의 멤버(CS9363)를 호출할 때 컨텍스트를 사용하십시오. C# 15 컴파일러는 선언뿐만 아니라 호출 사이트에서 안전하지 않은 멤버 사용량을 추적합니다.
  • unsafe 컨텍스트를 사용해야 하는 경우는 new() 제약 조건이 RequiresUnsafe 또는 extern로 표시된 생성자(CS9376)를 호출해야 할 때입니다. 제네릭 인스턴스화는 생성자를 암시적으로 호출하므로 호출 컨텍스트가 안전하지 않아야 합니다.

안전하지 않은 회원 안전 계약

  • CS9364: 안전하지 않은 멤버 'member'는 안전한 멤버 'member'를 재정의할 수 없습니다.
  • CS9365: 안전하지 않은 멤버 'member'는 안전한 멤버 'member'를 암시적으로 구현할 수 없습니다.
  • CS9366: 안전하지 않은 멤버 'member'가 안전한 멤버 'member'를 구현할 수 없습니다.
  • CS9367: RequiresUnsafeAttribute 이 기호에 적용할 수 없습니다.
  • CS9368: RequiresUnsafeAttribute 업데이트된 메모리 안전 규칙에 따라만 유효합니다.
  • CS9377: 'unsafe' 한정자는 현재 메모리 안전 규칙에 따라 여기에 아무런 영향을 주지 않습니다.

이러한 진단은 안전하지 않은 것으로 표시된 멤버에 대해 C# 15 안전 계약 규칙을 적용합니다. 컴파일러는 안전하지 않은 멤버가 기본 클래스 및 인터페이스에서 설정한 안전 기대치를 위반하지 않도록 합니다. 자세한 내용은 안전하지 않은 코드와 포인터 및키워드를unsafe 참조하세요.

  • 안전하지 않은 멤버(CS9364)를 사용하여 안전한 기본 멤버를 재정의하지 마세요. 재정의(오버라이드)는 기본 멤버의 안전 계약을 유지해야 합니다. 기본 멤버가 안전한 경우 재정의도 안전해야 합니다. unsafe 한정자 또는 RequiresUnsafeAttribute 재정의 멤버에서 제거하거나 기본 멤버를 안전하지 않은 것으로 표시합니다.
  • 안전하지 않은 멤버를 사용하여 안전한 인터페이스 멤버를 암시적으로 구현하지 마세요(CS9365). 형식이 인터페이스 멤버를 암시적으로 구현하는 경우 인터페이스를 통한 호출자는 안전한 작업을 기대합니다. 구현 멤버에서 안전하지 않은 지정을 제거하거나 명시적 인터페이스 구현을 사용합니다.
  • 안전하지 않은 멤버를 사용하여 안전한 인터페이스 멤버를 명시적으로 구현하지 마세요(CS9366). 명시적 구현이 있더라도 인터페이스 멤버의 안전 계약은 유지되어야 합니다.
  • 지원되는 기호 형식(RequiresUnsafeAttribute)에만 적용 합니다. 이 특성은 메서드, 속성, 이벤트, 생성자 및 형식에 적용할 수 있지만 모든 기호 종류가 지원하는 것은 아닙니다.
  • 업데이트된 메모리 안전 규칙을 사용하도록 설정합니다 RequiresUnsafeAttribute (CS9368). 이 특성은 C# 15의 구체화된 메모리 안전 모델의 일부이며 레거시 규칙에 따라 인식되지 않습니다. 프로젝트가 업데이트된 규칙을 지원하는 언어 버전을 대상으로 지정하는지 확인합니다.
  • unsafe 효과가 없는 경우 한정자를 제거합니다(CS9377). 현재 메모리 안전 규칙에 따라 특정 컨텍스트에서는 unsafe 수식자가 필요하지 않거나 이점을 주지 못합니다. 컴파일러는 불필요한 주석을 정리할 수 있도록 한정자가 의미가 없을 때 경고합니다.

고정 크기 버퍼

  • CS1641: 고정 크기 버퍼 필드에는 필드 이름 다음에 배열 크기 지정자가 있어야 합니다.
  • CS1642: 고정 크기 버퍼 필드는 구조체의 멤버일 수 있습니다.
  • CS1663: 고정 크기 버퍼 유형은 다음 boolbyteshortintlongcharsbyteushortuintulongfloatdouble중 하나여야 합니다.
  • CS1665: 고정 크기 버퍼의 길이가 0보다 커야 합니다.
  • CS1666: 고정되지 않은 식에 포함된 고정 크기 버퍼는 사용할 수 없습니다. 고정 문을 사용해 보십시오
  • CS1708: 고정 크기 버퍼는 로컬 또는 필드를 통해서만 액세스할 수 있습니다.
  • CS1716: 'System.Runtime.CompilerServices.FixedBuffer' 특성을 사용하지 마세요. 대신 '고정' 필드 한정자를 사용합니다.
  • CS7092: 고정 버퍼에는 하나의 차원만 있을 수 있습니다.
  • CS8372: 속성에 '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) 대신 필드 한정자를 사용합니다. 속성에 이 특성을 적용하지 마세요(CS8372).
  • 단 하나의 차원으로 고정 버퍼를 선언합니다(CS7092). 다차원 고정 버퍼는 지원되지 않습니다.
  • 고정 크기 버퍼를 필드로 ref 선언하지 마세요(CS9049). 고정 크기 버퍼는 값 필드여야 합니다.

함수 포인터

  • CS8812: > 메서드 그룹 'method'를 함수가 아닌 포인터 형식 'type'으로 변환할 수 없습니다.

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