diff options
| author | nsfisis <nsfisis@gmail.com> | 2022-11-19 14:23:32 +0900 |
|---|---|---|
| committer | nsfisis <nsfisis@gmail.com> | 2022-11-19 14:25:59 +0900 |
| commit | 6209453817da9922f28bac1bb1522c6d380630ab (patch) | |
| tree | 19e0699e751af387d549d6720ca215c8065b3c0c /public/posts/2021-10-02/cpp-you-can-use-keywords-in-attributes/index.html | |
| parent | 0cafa073914b5e0b162b735a7f8445fb2aa8a604 (diff) | |
| download | blog.nsfisis.dev-6209453817da9922f28bac1bb1522c6d380630ab.tar.gz blog.nsfisis.dev-6209453817da9922f28bac1bb1522c6d380630ab.tar.zst blog.nsfisis.dev-6209453817da9922f28bac1bb1522c6d380630ab.zip | |
Hugo to Asciidoctor
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 | 209 |
1 files changed, 209 insertions, 0 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 new file mode 100644 index 0000000..16a8188 --- /dev/null +++ b/public/posts/2021-10-02/cpp-you-can-use-keywords-in-attributes/index.html @@ -0,0 +1,209 @@ +<!DOCTYPE html> +<html lang="ja-JP"> + <head> + <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="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"> + <link rel="stylesheet" href="/style.css"> + <link rel="stylesheet" href="/custom.css"> + </head> + <body class="single"> + <header class="header"> + <nav class="nav"> + <p class="logo"> + <a href="/">REPL: Rest-Eat-Program Loop</a> + </p> + </nav> + </header> + <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> + + </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> + + </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> + </div> + </article> + </main> + <footer class="footer"> + © 2021 nsfisis + </footer> + </body> +</html> |
