컴파일러는 Attribute 정보를 사용해 정보 메시지를 생성 하거나 특성 사용 코드를 컴파일할 때 특정한 동작을 할 수 있다. 사용법은 아래와 같다.
[[Attribute구문]]
필수는 아니지만, 알아두면 유용하게 사용할 수 있는 몇 가지 키워드를 소개하려 한다.
함수의 선언에서만 가능하며, 함수가 return문을 실행 하거나 함수의 끝에 도달 하여 함수가 반환되지 않음을 나타낸다. 이를 통해 컴파일러가 여러 최적화를 수행할 수 있게한다.
이로인해 호출에 관련된 임시 상태들을 저장하고 불러올 필요가 없어지고 호출이 돌아오지 않아, 불필요한 블럭 내 하위 코드들을 지울 수 있다.
[[noreturn]]으로 선언된 함수가 어떠한 값(void포함) 반환하려 할 경우의 결과는 미정(undefined)이다.
[[noreturn]] void foo()
{
throw error; //OK
}
int main()
{
foo();
// 이 아래 코드는 실행되지 않음
...
}
[[noreturn]]으로 선언된 표준 함수
std::_Exit
std::exit
std::quick_exit
std::abort
std::terminate
std::rethrow_exception
std::throw_with_nested
std::nested_exception::rethrow_nested
함수의 반환 값이 삭제 되지 않도록 지정 한다. 만약 버려질 경우 컴파일 경고 발생
[[nodiscard]]
int foo(int i) { return i * i; }
int main()
{
foo(42); //warning C4834: discarding return value of function with 'nodiscard' attribute
return 0;
}
foo()의 반환값이 아무 것도 하지 않고 버려져 컴파일러가 알려준다.
함수를 사용 하기에 적합 하지 않거나 이후 버전의 라이브러리 인터페이스에 존재 하지 않을 수 있음을 지정 한다. 컴파일러는 클라이언트 코드에서 함수를 호출 하려고 할 때, 사용자에게 메시지를 전달한다.
클래스의 선언, typedef 이름, 변수, 비정적 데이터 멤버, 함수, 네임 스페이스, 열거형, 열거자 또는 템플릿 특수화에 적용할 수 있다.
[[deprecated("Use new_foo()")]]
void old_foo() {}
void new_foo() {}
int main()
{
old_foo(); // "Use new_foo() "
return 0;
}
switch 문에서만 사용가능하다. [[fallthrough]] 이후의 case를 실행하고 싶을 때 사용한다. 예를들어 실수로 break를 넣지 않은 것일 수도 있고 일부러 넣지 않은 것일 수도있는데 이럴 때 컴파일러의 경고를 막고 명시적으로 표시하기 위함이다.
void f(int n) {
void g(), h(), i();
switch (n) {
case 1:
case 2:
g();
[[fallthrough]];
case 3: // [[fallthrough]] 사용으로 경고없음
h();
case 4: // 컴파일러 Warning
if(n < 3) {
i();
[[fallthrough]]; // OK
}
else {
return;
}
case 5:
while (false) {
[[fallthrough]]; // 잘못된 형식, 다음이 동일한 반복의 일부가 아님
}
case 6:
[[fallthrough]]; // 잘못된 형식, 뒤에 아무 것도 없음
}
}
내용 추가 예정