Namespaces
Variants

Attribute specifier sequence (since C++11)

From cppreference.net
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Functions
Function declaration
Lambda function expression
inline specifier
Dynamic exception specifications ( until C++17* )
noexcept specifier (C++11)
Exceptions
Namespaces
Types
Specifiers
constexpr (C++11)
consteval (C++20)
constinit (C++20)
Storage duration specifiers
Initialization
Expressions
Alternative representations
Literals
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Utilities
Attributes (C++11)
Types
typedef declaration
Type alias declaration (C++11)
Casts
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
Miscellaneous

타입, 객체, 코드 등에 대한 구현에서 정의하는 속성들을 소개합니다.

목차

구문

[[ attribute-list ]] (C++11부터)
[[ using attribute-namespace : attribute-list ]] (C++17부터)

여기서 attribute-list 는 쉼표로 구분된 0개 이상의 attribute  시퀀스입니다 (줄임표 ... 로 끝나 pack expansion 을 나타낼 수 있음)

identifier (1)
attribute-namespace :: identifier (2)
identifier ( argument-list  (선택 사항) ) (3)
attribute-namespace :: identifier ( argument-list  (선택 사항) ) (4)

여기서 attribute-namespace identifier 이고 argument-list 는 괄호, 대괄호, 중괄호가 균형 잡힌 토큰 시퀀스( balanced-token-seq )입니다.

1) 단순 속성, 예를 들어 [ [ noreturn ] ] .
2) 네임스페이스를 가진 속성(attribute), 예를 들어 [ [ gnu :: unused ] ] .
3) 인수를 갖는 속성(attribute), 예를 들어 [ [ deprecated ( "because" ) ] ] 와 같은 것.
4) 네임스페이스와 인수 목록을 모두 갖는 특성.

using namespace: 가 속성 목록의 시작 부분에 나타나면, 속성 목록의 다른 속성들은 네임스페이스를 지정할 수 없습니다: using에서 지정된 네임스페이스가 모든 속성에 적용됩니다:

[[using CC: opt(1), debug]] // same as [[CC::opt(1), CC::debug]]
[[using CC: CC::opt(1)]] // error: cannot combine using and scoped attribute
(C++17부터)

설명

속성(Attributes)은 GNU 및 IBM 언어 확장 __attribute__((...)) , Microsoft 확장 __declspec() 등과 같은 구현 정의 언어 확장을 위한 통합 표준 구문을 제공합니다.

속성은 C++ 프로그램의 거의 모든 곳에서 사용될 수 있으며, 거의 모든 것에 적용될 수 있습니다: 타입, 변수, 함수, 이름, 코드 블록, 전체 번역 단위에 적용 가능하지만, 각 특정 속성은 구현에서 허용되는 곳에서만 유효합니다: [[expect_true]] if 문과 함께만 사용될 수 있고 클래스 선언에는 사용될 수 없는 속성일 수 있습니다. [[omp::parallel()]] 는 코드 블록이나 for 루프에 적용될 수 있지만 int 타입 등에는 적용될 수 없는 속성일 수 있습니다 (이 두 속성은 가상의 예시이며, 표준 및 일부 비표준 속성에 대해서는 아래를 참조하십시오).

선언에서 속성은 전체 선언 앞에 나타날 수도 있고, 선언된 엔티티의 이름 바로 뒤에 나타날 수도 있으며, 이 경우 결합됩니다. 대부분의 다른 상황에서는 속성이 바로 앞의 엔티티에 적용됩니다.

alignas 지정자 는 속성 지정자 시퀀스의 일부이지만, 다른 구문을 가지고 있습니다. 이는 [[...]] 속성이 나타나는 위치에 나타날 수 있으며, (해당 위치에서 alignas 가 허용되는 경우) 이들과 혼합하여 사용될 수 있습니다.

두 개의 연속된 왼쪽 대괄호 토큰( [[ )은 attribute-specifier를 도입할 때나 attribute argument 내부에서만 나타날 수 있습니다.

void f()
{
    int y[3];
    y[[] { return 0; }()] = 1;  // 오류
    int i [[cats::meow([[]])]]; // 정상
}

아래에 나열된 표준 속성 외에도, 구현체들은 구현 정의 동작을 가진 임의의 비표준 속성을 지원할 수 있습니다. 구현체가 알 수 없는 모든 속성은 오류를 발생시키지 않고 무시됩니다. (C++17부터)

attribute-namespace 가 없는 속성과 attribute-namespace 이름이 std 이거나 std 뒤에 하나 이상의 숫자가 오는 속성은 향후 표준화를 위해 예약됩니다. 즉, 모든 비표준 속성은 구현체에서 제공하는 attribute-namespace 에 있습니다, 예를 들어 [[gnu::may_alias]] , [[clang::trivial_abi]] , [[msvc::noop_dtor]] 와 같습니다.

(C++20부터)

표준 속성

다음 속성들은 C++ 표준에 의해 정의됩니다.

표준 속성은 구문적으로 무시될 수 없습니다: 구문 오류를 포함할 수 없으며, 올바른 대상에 적용되어야 하고, 인수 내의 개체들은 ODR-use 되어야 합니다.

표준 속성은 의미적으로 무시될 수도 없습니다: 특정 표준 속성의 모든 인스턴스가 제거된 상태의 동작은 원래 속성이 존재했던 프로그램에 대해 적합한 동작이었을 것입니다.

(C++11)
함수가 반환하지 않음을 나타냄
(속성 지정자)
(C++11) (C++26에서 제거됨)
release-consume의 종속성 체인이 함수 내외로 전파됨을 나타냄 std::memory_order
(속성 지정자)
[[ deprecated ]] [[ deprecated (" reason ")]]
(C++14) (C++14)
이 속성으로 선언된 이름이나 엔티티의 사용이 허용되지만, 어떤 이유 로 권장되지 않음을 나타냄
(속성 지정자)
(C++17)
이전 case 레이블에서의 폴스루가 의도적이며, 폴스루에 대해 경고하는 컴파일러에 의해 진단되지 않아야 함을 나타냄
(속성 지정자)
(C++17)
사용되지 않은 엔티티에 대한 컴파일러 경고를 억제함
(속성 지정자)
[[ nodiscard ]] [[ nodiscard (" reason ")]]
(C++17) (C++20)
반환값이 폐기될 경우 컴파일러가 경고를 발생하도록 권장함
(속성 지정자)
(C++20) (C++20)
문을 통한 실행 경로가 다른 어떤 실행 경로보다 더 많거나 적을 가능성이 있는 경우에 대해 컴파일러가 최적화해야 함을 나타냄
(속성 지정자)
(C++20)
비정적 데이터 멤버가 해당 클래스의 다른 모든 비정적 데이터 멤버와 구별되는 주소를 가질 필요가 없음을 나타냄
(속성 지정자)
[[ assume ( expression )]]
(C++23)
주어진 지점에서 표현식 이 항상 true 로 평가됨을 지정함
(속성 지정자)
(C++26)
객체가 초기화되지 않으면 불확정 값을 가짐을 지정함
(속성 지정자)
함수 정의가 synchronized 문 에서의 호출에 대해 최적화되어야 함을 나타냄
(속성 지정자)

참고 사항

주어진 플랫폼에서 각 개별 속성의 존재 여부는 __has_cpp_attribute 전처리기 매크로로 확인할 수 있습니다.

기능 테스트 매크로 표준 기능
__cpp_attributes 200809L (C++11) 속성(Attributes)
__cpp_namespace_attributes 201411L (C++17) 네임스페이스 속성(Attributes)

예제

[[gnu::always_inline]] [[gnu::hot]] [[gnu::const]] [[nodiscard]]
inline int f(); // 네 개의 속성을 가진 f 선언
[[gnu::always_inline, gnu::const, gnu::hot, nodiscard]]
int f(); // 위와 동일하지만 네 개의 속성을 포함하는 단일 속성 지정자 사용
// C++17:
[[using gnu : const, always_inline, hot]] [[nodiscard]]
int f[[gnu::always_inline]](); // 속성은 여러 지정자에 나타날 수 있음
int f() { return 0; }
int main() {}

결함 보고서

다음의 동작 변경 결함 보고서들은 이전에 발표된 C++ 표준에 소급 적용되었습니다.

DR 적용 대상 게시된 동작 올바른 동작
CWG 2079 C++11 [[ 가 속성 인수 내에 나타날 수 없었음 허용됨
CWG 2538 C++11 표준 속성을 구문적으로 무시할 수 있는지 불명확했음 금지됨
CWG 2695 C++11 표준 속성을 의미론적으로 무시할 수 있는지 불명확했음 금지됨
P2156R1 C++11 모든 표준 속성이 attribute-list 에서 최대 한 번만 나타나야 했음 요구되지 않음

참고 항목

__has_cpp_attribute - 속성의 존재 여부를 확인합니다
C documentation for Attributes specifier sequence

외부 링크

1. GCC의 속성 . 이러한 속성은 [[gnu::...]] 형태로 사용할 수 있습니다, SO 참조 .
2. Clang의 속성 .
3. MSVC의 속성 .