Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: CWG2518適用を前提として記述する #1260

Open
wants to merge 7 commits into
base: master
Choose a base branch
from

Conversation

yumetodo
Copy link
Member

@yumetodo yumetodo requested a review from yohhoy March 17, 2024 06:38
@yumetodo yumetodo self-assigned this Mar 17, 2024
@yumetodo
Copy link
Member Author

@yohhoy @akinomyoga 手が空いているときに見てもらってもいいでしょうか?劇的には変えず基本的には並べ替えているだけに一旦してみました。

Copy link
Member

@akinomyoga akinomyoga left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

構成的には LGTM です。後は細かいことだけ

  • static_assert文 → static_assert宣言
  • (元からあったみたいですが) テンプレート宣言時はテンプレート定義時の方がよいのではないかと思います。
  • インスタンス化 → 実体化? (このページでは 79fc60a 以前は実体化で統一されていたみたいです)


### `static_assert`文に関する例外

後に述べる2段階名前探索に関する注意点とは関係なく、C++23以降、もしくはCWG 2518が適用された環境においては、template文(もしくは適切な特殊化や`constexpr if`文の中の文)が実際にインスタンス化されるまで、`static_assert`文の宣言は遅延される。
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

実際にインスタンス化されるまで

表記揺れ。インスタンス化→実体化

template文(もしくは適切な特殊化やconstexpr if文の中の文)

表記揺れ。template → テンプレート? ところで template 文って何のことかよくわからないので具体的にできますか。

CWG 2518 を確認したら、"テンプレート定義時に式が評価された場合は static_assert 宣言は効果がない" と言っていて、別に評価や検証が遅延されるわけではないみたいです。つまり「(2段階名前探索の) 1段階目で false になっても何も起こらない」という形みたいです。

static_assert文の宣言は遅延

「宣言」って書いている時は何を意味していますか? この文書の他の部分ではテンプレートの定義時点のことを宣言と言っているように見えますが、ここでは static_assert の「実体化」もしくは「検証」のことを言っている?

あと「static_assert文」ではなくて「static_assert宣言」のような…。

Suggested change
後に述べる2段階名前探索に関する注意点とは関係なく、C++23以降、もしくはCWG 2518が適用された環境においては、template文(もしくは適切な特殊化や`constexpr if`文の中の文)が実際にインスタンス化されるまで`static_assert`文の宣言は遅延される
後に述べる2段階名前探索に関する注意点とは関係なく、C++23以降、もしくはCWG 2518が適用された環境においては、template文(もしくは適切な特殊化や`constexpr if`文の中の文)が実際に実体化されるまで`static_assert`文の検証は遅延される

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

構文要素としてのstatic_assertは、文(statement)ではなく宣言(declaration)の一種ですね。

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

で対応してみました。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

表記揺れ。template → テンプレート? ところで template 文って何のことかよくわからないので具体的にできますか。

これは対応する予定はありますか。P2593R1 の対応する記述に従えば "template 文" ではなくて "テンプレート” でしょうか (edit: lang/cpp11/static_assert.md にも同様のものがありますね)。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(元からあったみたいですが) テンプレート宣言時はテンプレート定義時の方がよいのではないかと思います。

あと、これについてもご確認いただけたらと思います。

lang/cpp17/if_constexpr.md Outdated Show resolved Hide resolved
Co-authored-by: Koichi Murase <myoga.murase@gmail.com>
```cpp
template<bool> struct inferior_static_assert_failure;
template<> struct inferior_static_assert_failure<true>{ enum { value = 1 }; };
#define INFERIOR_STATIC_ASSERT(B) typedef char inferior_static_assert[sizeof(inferior_static_assert_failure<bool(B)>::value)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

後続趣旨「CWG 2518未適用のstatic_assertでも同じ問題がある」との直接対比可能な構造にしたいのだと推察しますが、
経緯や結論を知らない読者からすると、複雑な INFERIOR_STATIC_ASSERT マクロの唐突な登場は混乱を招かないでしょうか?

(とコメントしつつ、良い案が思い浮かばず申し訳ない)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

弱い提案:「つまり次の例は意図と異なる挙動を示す。」+INFERIOR_STATIC_ASSERT 利用例示を削除してしまっても、文意は壊れないと思いました。

(提案適用後の構成)

2段階名前探索における注意点
constexpr if文で、実行されない方のstatementは廃棄文(discarded statement)となり、文の実体化を防ぐ。言い換えると、2段階名前探索における依存名(dependent name)は、廃棄文の場合検証されない。また文が実体化されないのだから通常のif文と同じくもちろん実行時に実行もされない。CWG 2518が適用されていない環境においてはstatic_assertでも同じ現象が発生する。

(CWG 2518適用前の static_assert 問題点を指摘する例示コード)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

INFERIOR_STATIC_ASSERTが唐突に過ぎるというのはそのとおりなんですが、これ相当のマクロを自作している古いプロジェクトをC++17対応させたあとに、中途半端に古いコードを良く知らずにコピペしてくるときに引っかかる落とし穴なのかなと思っていました(限定的すぎますよね・・・)。

提案についてはちょっと週末寝かせて考えてみます。

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

3da7c5d

除去することにしました。

@@ -140,51 +194,25 @@ int main()
}
```

`constexpr if`文の条件式内は実体化が起きる。したがって実体化するとコンパイルエラーになるものは書いてはいけない
上の例では`false_v`を作ったが、ラムダ式でも同様のことができる。ラムダ式はそれが記述された位置から見て最小のスコープ (ブロックスコープ/クラススコープ/名前空間スコープ) で宣言されるクラスとして扱われる。例えば、下の例では`f()`という関数テンプレート内で宣言される。関数テンプレート内のクラスは依存名になるため、テンプレートの宣言時に検証されず、テンプレート実体化まで評価を遅らせることができる
Copy link
Member

@yohhoy yohhoy Mar 19, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

弱い意見:古いコンパイラへに対する回避策提示は、P2593R1 で言及されている信頼性の高い方式1つで十分だと思います。

2.2 Workarounds
As a result of static_assert(false) not working, people turn to workarounds. Which are, basically: how can I write false in a sufficiently complex way so as to confuse the compiler?

Some of these workarounds actually still do run afoul of the above rule, but compilers aren’t smart enough to diagnose them, so they Just Happen To Work. Checks like: [...]

2.3 Valid Workaround
A more valid workaround is to have some template that is always false (e.g. from this answer):
static_assert(always_false<T>::value);
[...] This is really the only real workaround for this problem, and is something that people have to be taught explicitly as a workaround.

本件に関連する言語仕様解釈は難解なため、条件部にラムダ式を用いる遅延false実装の妥当性について、私個人(yohhoy)は確証をもてません。

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

その記述はもともと constexpr if と local struct の評価のタイミングについてでの @yohhoy さんの回答がもとになっていた気がしますね・・・。cppreffjpに書くのを提案したのは私ですが・・・。

回避策として複数あげる必要性が薄らいだのは確かですが、積極的に除去する動機が自分にはないです。

ref: #577
cc: @alphya

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

本コメントの趣旨は「C++言語リファレンスという特性を踏まえると、古い処理系向けの回避策として複数選択肢を提示し読者を迷わせる必然性はない」です。

PS. teratailサイトでの回答を引き合いに出されていますが、これは2018年当時の質問に答えただけです。この部分については私としては困惑しかありません。

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

編集方針 - 正確なものに不要な情報はない という話も…。(追記: 個人的にはどっちつかずです)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ffb8d64

時間を開けて読み返した感じ、ないほうがスッキリするので思い切って消しました。うまくハマるように復活させられるならばそういう編集を後の人が行うことを止めるものではありません。

編集方針「正確なものに不要な情報はない」はあるものの、全体の構成として必要性を感じなくなったので除去する。

内容そのものをうまく当てはまる形で復活させられるならばそれに異議を唱えるものではないが、いい方法が浮かばなかった。

ref:
- #1260 (comment)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

CWG 2518の影響調査
3 participants