diff options
| author | nsfisis <nsfisis@gmail.com> | 2022-12-23 23:27:09 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2023-03-06 01:46:04 +0900 |
| commit | 88ba6cfe220216f371f8756921059fac51a21262 (patch) | |
| tree | f272db2a0a3340f103df6618f19a101e65941b37 /public/posts/2021-10-02/cpp-you-can-use-keywords-in-attributes/index.html | |
| parent | 8f988a6e899aed678406ddfac1be4ef105439274 (diff) | |
| download | blog.nsfisis.dev-88ba6cfe220216f371f8756921059fac51a21262.tar.gz blog.nsfisis.dev-88ba6cfe220216f371f8756921059fac51a21262.tar.zst blog.nsfisis.dev-88ba6cfe220216f371f8756921059fac51a21262.zip | |
AsciiDoc to DocBook
Diffstat (limited to 'public/posts/2021-10-02/cpp-you-can-use-keywords-in-attributes/index.html')
| -rw-r--r-- | public/posts/2021-10-02/cpp-you-can-use-keywords-in-attributes/index.html | 350 |
1 files changed, 172 insertions, 178 deletions
diff --git a/public/posts/2021-10-02/cpp-you-can-use-keywords-in-attributes/index.html b/public/posts/2021-10-02/cpp-you-can-use-keywords-in-attributes/index.html index d844baa..233908b 100644 --- a/public/posts/2021-10-02/cpp-you-can-use-keywords-in-attributes/index.html +++ b/public/posts/2021-10-02/cpp-you-can-use-keywords-in-attributes/index.html @@ -4,18 +4,14 @@ <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta name="author" content="nsfisis"> - <meta name="copyright" content="© nsfisis"> + <meta name="copyright" content="© 2021 nsfisis"> <meta name="description" content="C++ の属性構文の属性名には、キーワードが使える。ネタ記事。"> <meta name="keywords" content="C++,C++ 17"> <link rel="icon" type="image/svg+xml" href="/favicon.svg"> - <title>【C++】属性構文の属性名にはキーワードが使える | REPL: Rest-Eat-Program Loop</title> - - <link rel="stylesheet" href="/hl.css?208c52e3b7c9db1cad782c5d30b4698f"> - - <link rel="stylesheet" href="/style.css?779b1a3debcaeba619f6fe500e93d525"> - - <link rel="stylesheet" href="/custom.css?a649ea3528d4b626fb636505d94c1144"> - + <title>【C++】 属性構文の属性名にはキーワードが使える | REPL: Rest-Eat-Program Loop</title> + <link rel="stylesheet" href="/hl.css?h=208c52e3b7c9db1cad782c5d30b4698f"> + <link rel="stylesheet" href="/style.css?h=779b1a3debcaeba619f6fe500e93d525"> + <link rel="stylesheet" href="/custom.css?h=a649ea3528d4b626fb636505d94c1144"> </head> <body class="single"> <header class="header"> @@ -28,183 +24,181 @@ <main class="main"> <article class="post-single"> <header class="post-header"> - <h1 class="post-title">【C++】属性構文の属性名にはキーワードが使える</h1> - - <ul class="post-tags"> - - <li class="tag"> - <a href="/tags/cpp/">C++</a> - </li> - - <li class="tag"> - <a href="/tags/cpp17/">C++ 17</a> - </li> - - </ul> - + <h1 class="post-title">【C++】 属性構文の属性名にはキーワードが使える</h1> + <ul class="post-tags"> + <li class="tag"> + <a href="/tags/cpp">C++</a> + </li> + <li class="tag"> + <a href="/tags/cpp17">C++ 17</a> + </li> + </ul> </header> <div class="post-content"> <section> <h2 id="changelog">更新履歴</h2> <ol> - - <li class="revision"> - <time datetime="2021-10-02">2021-10-02</time>: Qiita から移植 - </li> - + <li class="revision"> + <time datetime="2021-10-02">2021-10-02</time>: Qiita から移植 + </li> </ol> </section> - <div class="paragraph"> -<p>この記事は Qiita から移植してきたものです。 元 URL: -<a href="https://qiita.com/nsfisis/items/94090937bcf860cfa93b" class="bare">https://qiita.com/nsfisis/items/94090937bcf860cfa93b</a></p> -</div> -<hr> -<div class="paragraph"> -<p>タイトル落ち。まずはこのコードを見て欲しい。</p> -</div> -<div id="source." class="listingblock"> -<div class="content"> -<pre class="rouge highlight"><code data-lang="cpp"><span class="cp">#include</span> <span class="cpf"><iostream></span><span class="cp"> -</span> -<span class="p">[[</span><span class="k">alignas</span><span class="p">]]</span> <span class="p">[[</span><span class="k">alignof</span><span class="p">]]</span> <span class="p">[[</span><span class="n">and</span><span class="p">]]</span> <span class="p">[[</span><span class="n">and_eq</span><span class="p">]]</span> <span class="p">[[</span><span class="k">asm</span><span class="p">]]</span> <span class="p">[[</span><span class="k">auto</span><span class="p">]]</span> <span class="p">[[</span><span class="n">bitand</span><span class="p">]]</span> -<span class="p">[[</span><span class="n">bitor</span><span class="p">]]</span> <span class="p">[[</span><span class="kt">bool</span><span class="p">]]</span> <span class="p">[[</span><span class="k">break</span><span class="p">]]</span> <span class="p">[[</span><span class="k">case</span><span class="p">]]</span> <span class="p">[[</span><span class="k">catch</span><span class="p">]]</span> <span class="p">[[</span><span class="kt">char</span><span class="p">]]</span> <span class="p">[[</span><span class="kt">char16_t</span><span class="p">]]</span> -<span class="p">[[</span><span class="kt">char32_t</span><span class="p">]]</span> <span class="p">[[</span><span class="k">class</span><span class="p">]]</span> <span class="p">[[</span><span class="n">compl</span><span class="p">]]</span> <span class="p">[[</span><span class="k">const</span><span class="p">]]</span> <span class="p">[[</span><span class="k">const_cast</span><span class="p">]]</span> <span class="p">[[</span><span class="k">constexpr</span><span class="p">]]</span> -<span class="p">[[</span><span class="k">continue</span><span class="p">]]</span> <span class="p">[[</span><span class="k">decltype</span><span class="p">]]</span> <span class="p">[[</span><span class="k">default</span><span class="p">]]</span> <span class="p">[[</span><span class="k">delete</span><span class="p">]]</span> <span class="p">[[</span><span class="k">do</span><span class="p">]]</span> <span class="p">[[</span><span class="kt">double</span><span class="p">]]</span> -<span class="p">[[</span><span class="k">dynamic_cast</span><span class="p">]]</span> <span class="p">[[</span><span class="k">else</span><span class="p">]]</span> <span class="p">[[</span><span class="k">enum</span><span class="p">]]</span> <span class="p">[[</span><span class="k">explicit</span><span class="p">]]</span> <span class="p">[[</span><span class="k">export</span><span class="p">]]</span> <span class="p">[[</span><span class="k">extern</span><span class="p">]]</span> <span class="p">[[</span><span class="nb">false</span><span class="p">]]</span> -<span class="p">[[</span><span class="k">final</span><span class="p">]]</span> <span class="p">[[</span><span class="kt">float</span><span class="p">]]</span> <span class="p">[[</span><span class="k">for</span><span class="p">]]</span> <span class="p">[[</span><span class="k">friend</span><span class="p">]]</span> <span class="p">[[</span><span class="k">goto</span><span class="p">]]</span> <span class="p">[[</span><span class="k">if</span><span class="p">]]</span> <span class="p">[[</span><span class="kr">inline</span><span class="p">]]</span> <span class="p">[[</span><span class="kt">int</span><span class="p">]]</span> -<span class="p">[[</span><span class="kt">long</span><span class="p">]]</span> <span class="p">[[</span><span class="k">mutable</span><span class="p">]]</span> <span class="p">[[</span><span class="k">namespace</span><span class="p">]]</span> <span class="p">[[</span><span class="k">new</span><span class="p">]]</span> <span class="p">[[</span><span class="k">noexcept</span><span class="p">]]</span> <span class="p">[[</span><span class="n">not</span><span class="p">]]</span> <span class="p">[[</span><span class="n">not_eq</span><span class="p">]]</span> -<span class="p">[[</span><span class="nb">nullptr</span><span class="p">]]</span> <span class="p">[[</span><span class="k">operator</span><span class="p">]]</span> <span class="p">[[</span><span class="n">or</span><span class="p">]]</span> <span class="p">[[</span><span class="n">or_eq</span><span class="p">]]</span> <span class="p">[[</span><span class="k">override</span><span class="p">]]</span> <span class="p">[[</span><span class="k">private</span><span class="p">]]</span> -<span class="p">[[</span><span class="k">protected</span><span class="p">]]</span> <span class="p">[[</span><span class="k">public</span><span class="p">]]</span> <span class="p">[[</span><span class="k">register</span><span class="p">]]</span> <span class="p">[[</span><span class="k">reinterpret_cast</span><span class="p">]]</span> <span class="p">[[</span><span class="k">return</span><span class="p">]]</span> <span class="p">[[</span><span class="kt">short</span><span class="p">]]</span> -<span class="p">[[</span><span class="kt">signed</span><span class="p">]]</span> <span class="p">[[</span><span class="k">sizeof</span><span class="p">]]</span> <span class="p">[[</span><span class="k">static</span><span class="p">]]</span> <span class="p">[[</span><span class="k">static_assert</span><span class="p">]]</span> <span class="p">[[</span><span class="k">static_cast</span><span class="p">]]</span> <span class="p">[[</span><span class="k">struct</span><span class="p">]]</span> -<span class="p">[[</span><span class="k">switch</span><span class="p">]]</span> <span class="p">[[</span><span class="k">template</span><span class="p">]]</span> <span class="p">[[</span><span class="k">this</span><span class="p">]]</span> <span class="p">[[</span><span class="k">thread_local</span><span class="p">]]</span> <span class="p">[[</span><span class="k">throw</span><span class="p">]]</span> <span class="p">[[</span><span class="nb">true</span><span class="p">]]</span> <span class="p">[[</span><span class="k">try</span><span class="p">]]</span> -<span class="p">[[</span><span class="k">typedef</span><span class="p">]]</span> <span class="p">[[</span><span class="k">typeid</span><span class="p">]]</span> <span class="p">[[</span><span class="k">typename</span><span class="p">]]</span> <span class="p">[[</span><span class="k">union</span><span class="p">]]</span> <span class="p">[[</span><span class="kt">unsigned</span><span class="p">]]</span> -<span class="p">[[</span><span class="k">virtual</span><span class="p">]]</span> <span class="p">[[</span><span class="kt">void</span><span class="p">]]</span> <span class="p">[[</span><span class="k">volatile</span><span class="p">]]</span> <span class="p">[[</span><span class="kt">wchar_t</span><span class="p">]]</span> <span class="p">[[</span><span class="k">while</span><span class="p">]]</span> <span class="p">[[</span><span class="n">xor</span><span class="p">]]</span> <span class="p">[[</span><span class="n">xor_eq</span><span class="p">]]</span> -<span class="c1">// [[using]]</span> -<span class="kt">int</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span> - <span class="n">std</span><span class="o">::</span><span class="n">cout</span> <span class="o"><<</span> <span class="s">"Hello, World!"</span> <span class="o"><<</span> <span class="n">std</span><span class="o">::</span><span class="n">endl</span><span class="p">;</span> -<span class="p">}</span></code></pre> -</div> -</div> -<div class="quoteblock"> -<blockquote> -<div class="paragraph"> -<p>コンパイラのバージョン $ clang++ –version Apple clang version 11.0.0 -(clang-1100.0.33.8) Target: x86_64-apple-darwin19.6.0 Thread model: -posix InstalledDir: -/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin</p> -</div> -<div class="paragraph"> -<p>コンパイルコマンド (C17指定) $ clang –std=c++17 hoge.cpp</p> -</div> -</blockquote> -</div> -<div class="paragraph"> -<p>この記事から得られるものはこれ以上ないので以下は蛇足になる。</p> -</div> -<div class="paragraph"> -<p>別件で cppreference.com の -<a href="https://en.cppreference.com/w/cpp/language/identifiers">identifier -のページ</a> を読んでいた時、次の文が目に止まった。</p> -</div> -<div class="quoteblock"> -<blockquote> -<div class="ulist"> -<ul> -<li> -<p>the identifiers that are keywords cannot be used for other purposes;</p> -<div class="ulist"> -<ul> -<li> -<p>The only place they can be used as non-keywords is in an -attribute-token. (e.g. <a id="private"></a> is a valid attribute) (since C++11)</p> -</li> -</ul> -</div> -</li> -</ul> -</div> -</blockquote> -</div> -<div class="paragraph"> -<p>キーワードでも属性として指定する場合は非キーワードとして使えるらしい。 -実際にやってみる。</p> -</div> -<div class="paragraph"> -<p>同サイトの <a href="https://en.cppreference.com/w/cpp/keyword">keywords のページ</a> -から一覧を拝借し、上のコードが出来上がった (C++17 -においてキーワードでないものなど、一部省いている)。 大量の警告 (unknown -attribute `〇〇' ignored) -がコンパイラから出力されるが、コンパイルできる。</p> -</div> -<div class="paragraph"> -<p>上のコードでは <code><a id="using"></a></code> をコメントアウトしているが、これは <code>using</code> -キーワードのみ属性構文の中で意味を持つからであり、このコメントアウトを外すとコンパイルに失敗する。</p> -</div> -<div id="source." class="listingblock"> -<div class="content"> -<pre class="rouge highlight"><code data-lang="cpp"><span class="c1">// using の例</span> -<span class="p">[[</span><span class="k">using</span> <span class="n">foo</span><span class="o">:</span> <span class="n">attr1</span><span class="p">,</span> <span class="n">attr2</span><span class="p">]]</span> <span class="kt">int</span> <span class="n">x</span><span class="p">;</span> <span class="c1">// [[foo::attr1, foo::attr2]] の糖衣構文</span></code></pre> -</div> -</div> -<div class="paragraph"> -<p>C++17 の仕様も見てみる (正確には標準化前のドラフト)。</p> -</div> -<div class="paragraph"> -<p>引用元: <a href="https://timsong-cpp.github.io/cppwp/n4659/dcl.attr#grammar-4" class="bare">https://timsong-cpp.github.io/cppwp/n4659/dcl.attr#grammar-4</a></p> -</div> -<div class="quoteblock"> -<blockquote> -<div class="paragraph"> -<p>If a keyword or an alternative token that satisfies the syntactic -requirements of an identifier is contained in an attribute-token, it is -considered an identifier.</p> -</div> -</blockquote> -</div> -<div class="paragraph"> -<p>「<code>identifier</code> の構文上の要件を満たすキーワードまたは代替トークンが -<code>attribute-token</code> に含まれている場合、<code>identifier</code> -とみなされる」とある。どうやら間違いないようだ。</p> -</div> -<div class="paragraph"> -<p>ところで、代替トークン (alternative token) とは <code>and</code> (<code>&</code>) や <code>bitor</code> -(<code>|</code>) などのことだが、<code>identifier</code> -の構文上の要件を満たさないような代替トークンなどあるのか? -疑問に思って調べたところ、代替トークンという語にはダイグラフも含まれるらしい -(参考: -<a href="https://timsong-cpp.github.io/cppwp/n4659/lex.digraph">同ドラフト</a>)</p> -</div> -<div class="ulist"> -<ul> -<li> -<p><code><%</code> → <code>{</code></p> -</li> -<li> -<p><code>%></code> → <code>}</code></p> -</li> -<li> -<p><code><:</code> → <code>[</code></p> -</li> -<li> -<p><code>:></code> → <code>]</code></p> -</li> -<li> -<p><code>%:</code> → <code>#</code></p> -</li> -<li> -<p><code>%:%:</code> → <code>##</code></p> -</li> -</ul> -</div> -<div class="paragraph"> -<p>「<code>identifier</code> -の構文上の要件を満たさないような代替トークン」はこれらが当てはまると思われる。</p> -</div> -<div class="paragraph"> -<p>調べた感想: 字句解析器か構文解析器が辛そう</p> -</div> + <p> + この記事は Qiita から移植してきたものです。 元 URL:<a xl:href="https://qiita.com/nsfisis/items/94090937bcf860cfa93b">https://qiita.com/nsfisis/items/94090937bcf860cfa93b</a> + </p> + + <p> + <hr> + </hr> + </p> + + <p> + タイトル落ち。まずはこのコードを見て欲しい。 + </p> + + <pre language="cpp" linenumbering="unnumbered"> + <code>#include <iostream> + +[[alignas]] [[alignof]] [[and]] [[and_eq]] [[asm]] [[auto]] [[bitand]] +[[bitor]] [[bool]] [[break]] [[case]] [[catch]] [[char]] [[char16_t]] +[[char32_t]] [[class]] [[compl]] [[const]] [[const_cast]] [[constexpr]] +[[continue]] [[decltype]] [[default]] [[delete]] [[do]] [[double]] +[[dynamic_cast]] [[else]] [[enum]] [[explicit]] [[export]] [[extern]] [[false]] +[[final]] [[float]] [[for]] [[friend]] [[goto]] [[if]] [[inline]] [[int]] +[[long]] [[mutable]] [[namespace]] [[new]] [[noexcept]] [[not]] [[not_eq]] +[[nullptr]] [[operator]] [[or]] [[or_eq]] [[override]] [[private]] +[[protected]] [[public]] [[register]] [[reinterpret_cast]] [[return]] [[short]] +[[signed]] [[sizeof]] [[static]] [[static_assert]] [[static_cast]] [[struct]] +[[switch]] [[template]] [[this]] [[thread_local]] [[throw]] [[true]] [[try]] +[[typedef]] [[typeid]] [[typename]] [[union]] [[unsigned]] +[[virtual]] [[void]] [[volatile]] [[wchar_t]] [[while]] [[xor]] [[xor_eq]] +// [[using]] +int main() { +std::cout << "Hello, World!" << std::endl; +}</code> + </pre> + + <blockquote> + <p> + コンパイラのバージョン $ clang++ –version Apple clang version 11.0.0 (clang-1100.0.33.8) Target: x86_64-apple-darwin19.6.0 Thread model: posix InstalledDir: /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin + </p> + + <p> + コンパイルコマンド (C17指定) $ clang –std=c++17 hoge.cpp + </p> + </blockquote> + + <p> + この記事から得られるものはこれ以上ないので以下は蛇足になる。 + </p> + + <p> + 別件で cppreference.com の<a xl:href="https://en.cppreference.com/w/cpp/language/identifiers">identifier のページ</a>を読んでいた時、次の文が目に止まった。 + </p> + + <blockquote> + <ul> + <li> + <p> + the identifiers that are keywords cannot be used for other purposes; + </p> + + <ul> + <li> + <p> + The only place they can be used as non-keywords is in an attribute-token. (e.g. [[private]] is a valid attribute) (since C++11) + </p> + </li> + </ul> + </li> + </ul> + </blockquote> + + <p> + キーワードでも属性として指定する場合は非キーワードとして使えるらしい。 実際にやってみる。 + </p> + + <p> + 同サイトの<a xl:href="https://en.cppreference.com/w/cpp/keyword">keywords のページ</a>から一覧を拝借し、上のコードが出来上がった (C++17 においてキーワードでないものなど、一部省いている)。 大量の警告 (unknown attribute `〇〇' ignored) がコンパイラから出力されるが、コンパイルできる。 + </p> + + <p> + 上のコードでは<code>[[using]]</code>をコメントアウトしているが、これは<code>using</code>キーワードのみ属性構文の中で意味を持つからであり、このコメントアウトを外すとコンパイルに失敗する。 + </p> + + <pre language="cpp" linenumbering="unnumbered"> + <code>// using の例 +[[using foo: attr1, attr2]] int x; // [[foo::attr1, foo::attr2]] の糖衣構文</code> + </pre> + + <p> + C++17 の仕様も見てみる (正確には標準化前のドラフト)。 + </p> + + <p> + 引用元:<a xl:href="https://timsong-cpp.github.io/cppwp/n4659/dcl.attr#grammar-4">https://timsong-cpp.github.io/cppwp/n4659/dcl.attr#grammar-4</a> + </p> + + <blockquote> + <p> + If a keyword or an alternative token that satisfies the syntactic requirements of an identifier is contained in an attribute-token, it is considered an identifier. + </p> + </blockquote> + + <p> + 「<code>identifier</code>の構文上の要件を満たすキーワードまたは代替トークンが<code>attribute-token</code>に含まれている場合、<code>identifier</code>とみなされる」とある。どうやら間違いないようだ。 + </p> + + <p> + ところで、代替トークン (alternative token) とは<code>and</code>(<code>&</code>) や<code>bitor</code>(<code>|</code>) などのことだが、<code>identifier</code>の構文上の要件を満たさないような代替トークンなどあるのか? 疑問に思って調べたところ、代替トークンという語にはダイグラフも含まれるらしい (参考:<a xl:href="https://timsong-cpp.github.io/cppwp/n4659/lex.digraph">同ドラフト</a>) + </p> + + <ul> + <li> + <p> + <code><%</code>→<code>{</code> + </p> + </li> + + <li> + <p> + <code>%></code>→<code>}</code> + </p> + </li> + + <li> + <p> + <code><:</code>→<code>[</code> + </p> + </li> + + <li> + <p> + <code>:></code>→<code>]</code> + </p> + </li> + + <li> + <p> + <code>%:</code>→<code>#</code> + </p> + </li> + + <li> + <p> + <code>%:%:</code>→<code>##</code> + </p> + </li> + </ul> + + <p> + 「<code>identifier</code>の構文上の要件を満たさないような代替トークン」はこれらが当てはまると思われる。 + </p> + + <p> + 調べた感想: 字句解析器か構文解析器が辛そう + </p> </div> - </article> </main> <footer class="footer"> |
