내장 어노테이션

내장 어노테이션 (Built-in annotations)

Crystal 언어에는 미리 정의되어 있는 어노테이션들이 몇 가지 있어요. 컴파일러가 이 어노테이션들을 코드 생성이나 deprecation 경고 같은 용도로 사용해요. 여기에 더해, Crystal 표준 라이브러리도 추가 어노테이션을 정의하고 있어요.

출처: Crystal 공식 문서

본문

컴파일러에게 C 라이브러리를 어떻게 링크할지 알려줘요. 자세한 내용은 lib 섹션에서 다뤄요.

참고: 더 자세한 내용은 Link API 문서를 확인해 보세요.

Extern

이 어노테이션을 Crystal struct에 붙이면, 그 struct를 lib 선언에서 사용할 수 있어요:

@[Extern]
struct MyStruct
end

lib MyLib
  fun my_func(s : MyStruct) # OK (gives an error without the Extern annotation)
end

struct가 C의 union처럼 동작하게 만들 수도 있어요. 다만 이건 꽤 안전하지 않을 수 있다는 점은 기억해 두세요:

# A struct to easily convert between Int32 codepoints and Chars
@[Extern(union: true)]
struct Int32OrChar
  property int = 0
  property char = '\0'
end

s = Int32OrChar.new
s.char = 'A'
s.int # => 65

s.int = 66
s.char # => 'B'

ThreadLocal

@[ThreadLocal] 어노테이션은 클래스 변수와 C 외부 변수에 붙일 수 있어요. 그 변수들을 스레드 로컬(thread local)로 만들어주죠.

class DontUseThis
  # One for each thread
  @[ThreadLocal]
  @@values = [] of Int32
end

ThreadLocal은 표준 라이브러리에서 런타임을 구현할 때 쓰여요. 그래서 표준 라이브러리 바깥에서는 굳이 필요하거나 쓰일 일이 없어요.

Packed

C struct를 packed로 표시해서, 필드 사이에 패딩 바이트가 자동으로 삽입되는 걸 막아줘요. 이건 보통 C 라이브러리가 명시적으로 packed struct를 사용할 때만 필요해요.

AlwaysInline

컴파일러에게 메서드를 항상 인라인하라는 힌트를 줘요:

@[AlwaysInline]
def foo
  1
end

NoInline

컴파일러에게 메서드 호출을 절대 인라인하지 말라고 알려줘요. 메서드가 yield 한다면 함수는 항상 인라인되기 때문에 이 어노테이션은 효과가 없어요.

@[NoInline]
def foo
  1
end

ReturnsTwice

메서드나 lib fun을 두 번 반환(return)하는 것으로 표시해요. C의 setjmp가 이런 함수의 예시예요.

Raises

메서드나 lib fun이 예외를 던질 수 있다고 표시해요. 이 내용은 callbacks 섹션에서 다뤄요.

CallConvention

lib fun의 호출 규약(call convention)을 나타내요. 예를 들어:

lib LibFoo
  @[CallConvention("X86_StdCall")]
  fun foo : Int32
end

유효한 호출 규약 목록은 다음과 같아요:

  • C (기본값)
  • Fast
  • Cold
  • WebKit_JS
  • AnyReg
  • X86_StdCall
  • X86_FastCall

참고: 더 자세한 내용은 LLVM 문서를 확인해 보세요.

Flags

enum을 "flags enum"으로 표시해요. 이렇게 하면 to_s 같은 일부 메서드의 동작이 달라져요.

참고: 더 자세한 내용은 Flags API 문서를 확인해 보세요.

Deprecated

어떤 기능(예: 메서드, 타입, 파라미터)을 deprecated로 표시해요.

Deprecation은 API 문서에 표시되고, deprecated 기능을 사용하면 컴파일러가 경고를 출력해요.

참고: 더 자세한 내용은 Deprecated API 문서를 확인해 보세요.

TargetFeature

deffun 범위로 특정 CPU 기능이나 CPU 모델을 활성화할 수 있게 해줘요. 그래서 SIMD 명령 같은 서로 다른 기능에 최적화된 함수들을 하나의 실행 파일에 담아 컴파일할 수 있어요. 예를 들어:

{% if flag?(:x86_64) %}
  @[TargetFeature("+avx2")]
  def foo_avx2
  end
{% end %}

참고: 더 자세한 내용은 TargetFeature API 문서를 확인해 보세요.

더 알아보기

  • @[Link]는 C 라이브러리 링크를, @[Extern]은 struct를 C 세계에서 쓸 수 있게 하는 데 쓰여요.
  • AlwaysInline/NoInline은 인라인 힌트, Raises/ReturnsTwice는 호출 동작을, CallConvention은 호출 규약을 다뤄요.
  • Flags 열거형에서는 Flags 어노테이션을, deprecated는 Deprecated로 표시해요.