関数一覧に出てこない関数があるNo.08164
colder さん 14/01/22 16:33
 
colderです
C++でアウトライン枠の関数一覧に出てこない関数があります。
今すぐ必要なものでもないですが、対応することは可能でしょうか?

・戻り値の型を後ろに書く形式で関数定義をしたとき
auto func() -> int
{
    return 0;
}

・lvalue/rvalue修飾されたメンバ関数
class foo
{
    int func() &&
    {
        return 0;
    }
};

参考
http://faithandbrave.hateblo.jp/entry/20080331/1206954005
http://faithandbrave.hateblo.jp/entry/20081204/1228382167

環境 win7 秀丸v8.40β1

[ ]
RE:08164 関数一覧に出てこない関数があるNo.08165
秀まるお さん 14/01/22 18:29
 
 colderさん、毎度情報ありがとうございます。関数一覧の処理は僕が作った処
理なので僕の方でお返事させていただきます。

 連絡いただいた関数宣言ですが、そういう宣言スタイルが追加されたことは全
然知らなくて、対応してませんでした。

 そんなに難しくないはずなので、とりあえず対応予定とさせていただきます。

[ ]
RE:08165 関数一覧に出てこない関数があるNo.08167
秀まるお さん 14/01/24 14:05
 
 先ほど直しました。

 次のV8.40β3で対応予定とさせていただきます。

[ ]
RE:08167 関数一覧に出てこない関数があるNo.08175
colder さん 14/01/29 23:24
 
colderです
対応ありがとうございます
秀丸ver8.40β3で試したところ、
戻り値の型を後ろに書く関数定義で、いくつか不具合が見付かりました。
class foo
{
public:
// lvalue/rvalue修飾された関数は表示されない
  auto func1() && -> int
  {
    return 1;
  }
// cv修飾された関数も表示されない
  auto func2() const  -> int
  {
    return 2;
  }
//例外を投げないと指定された関数も表示されない
  auto func3() noexcept -> int
  {
    return 3;
  }
// 当然、全てを合わせた形式も表示されない
  auto func4() const & noexcept -> int
  {
    return 4;
  }
//noexceptが関数名だと認識される
  int func5() noexcept(true)
  {
    return 5;
  }
};
//alignas が関数だと認識される
alignas(double) int z{6};

int main()
{
  foo x;
  int y = foo().func1()+ x.func2()+ x.func3()+x.func4()+x.func5()+z;
  cout << y << endl;

return 0;
}
//こうしてみると最近のC++の文法は訳分からない。

[ ]
RE:08175 関数一覧に出てこない関数があるNo.08176
秀まるお さん 14/01/30 12:04
 
 毎度いろんな情報ありがとうございます。

 とりあえず、前回教えていただいたサンプルだけ通るように直したという安易
な方法を取ってしまったのですが、実際にはもっとややこしいパターンがあるの
ですね。

 まずは、"->"の解釈についてですが、

■関数宣言の(...)から"{"の間に出没する"->"の解釈:

 現状:"->"が(...)の直後に現れた場合に限り、"->"から"{"までを無視する。
 修正:"->"が出現したら、その位置から"{"までを無視する。

 共通の処理:"->"の後ろをスキャンして、"{"が出現する前に";"があった場合
は関数と見なさない。それ以外は全部スキップ。

 ってしようかと思います。もし何か「それじゃまずいでしょ」ってパターンが
あったら教えて欲しいです。

> //noexceptが関数名だと認識される
>   int func5() noexcept(true)
>   {

 noexceptなんて物が追加されてるとは知りませんでした。

 throw(...)と同様の処理にて無視するように修正させていただきます。

> //alignas が関数だと認識される
> alignas(double) int z{6};

 これは、手元のVC++2012でコンパイルしたらエラーで通りませんでした。

 というか、「int z{6};」って表現自体が通らないです。

    int z[6];

 の間違いじゃないでしょうか。それか、

    int z = {6};

 ならコンパイルは通るようでしたけども。

 ただ、どっちにしても、"alignas"って名前は関数名として使えないような、
catchやsizeofとかと同様に弾く処理だけは入れさせていただきます。

 もし他にも何かこれは対応した方がいいって文法があれば教えて欲しいです。

[ ]
RE:08176 関数一覧に出てこない関数があるNo.08177
秀まるお さん 14/01/30 13:41
 
> > alignas(double) int z{6};
>
>  これは、手元のVC++2012でコンパイルしたらエラーで通りませんでした。

 ちなみにVC++2012ばalignasにはまだ未対応でした。参考になりませんでした。

 どっちにしても"alignas"を関数名として使えない例外文字列扱いするように
したので、今回のサンプルソースコードは正しく解釈できるようになりました。

 あと、秀Tagsの方が直してなかったので、そっちの方も直すようにします。

[ ]
RE:08176 関数一覧に出てこない関数があるNo.08178
colder さん 14/01/30 14:23
 
> というか、「int z{6};」って表現自体が通らないです。

統一された初期化構文とかいうやつです
http://faithandbrave.hateblo.jp/entry/20080625/1214384049
新しめのClangとかGCCならコンパイル出来ます
http://ideone.com/5wLSdK

> ただ、どっちにしても、"alignas"って名前は関数名として使えないような、
>catchやsizeofとかと同様に弾く処理だけは入れさせていただきます。

sizeofを弾く処理が入っているならalignofを弾く処理も必要かな。
alignofが関数名と認識されるような構文が思いつかないけど。
http://faithandbrave.hateblo.jp/entry/20080708/1215508071

> もし他にも何かこれは対応した方がいいって文法があれば教えて欲しいです。
二重の角括弧 [[...]]が現れた場合、その部分を無視って言う処理も必要になるかも
しれない。
一般化された属性とか言うやつです。
http://faithandbrave.hateblo.jp/entry/20081017/1224236745
[[noreturn]]以外専用のキーワードが与えられちゃったけど(C++14では[[deprecate
d]]が追加)

[ ]
RE:08176 関数一覧に出てこない関数があるNo.08179
colder さん 14/01/30 17:09
 
coldeです

> もし他にも何かこれは対応した方がいいって文法があれば教えて欲しいです。
強調定義でraw string literal や 数値の'による桁区切りなんかも対応した方がい
いかもしれません。

・raw string literal(C++11)
const char *s1 = R"(ここに改行や
"や\も自由に書ける)";
const char *s2 = R"delimitor(「"」と「(」の間には
16文字以内のほとんどの制御コード以外のASCII文字(《 ()\@`$》以外)を入れられる
「)」と「"」の間に同じ文字列入れて終了)delimitor";

・数値の'による桁区切り(C++14)
int i = 1'2'34'567'89; //数値を'で桁区切り出来る 区切り位置は任意
int j = 0x1234'5678'9abc'def0; //16進数や8進数、2進数もOK
double pi = 3.14159'26535'89793'23846 //浮動小数点もOK

・C#のquoted String
string a = @"ここに改行も\も自由に書ける""を書くときは二つ重ねる";
http://msdn.microsoft.com/en-us/library/362314fe.aspx

ユーザ定義の複数行コメント機能でも実現出来ますが#if 0〜#endifの強調表示が出
来ないです。
raw string literalとquoted Stringに関してはサクラエディタが一応対応しています。

[ ]
RE:08178 関数一覧に出てこない関数があるNo.08180
秀まるお さん 14/01/30 17:57
 
 教えていただいたalignof対応も追加させていただきます。

 [[...]]の無視の処理もついでに対応します。

 それと、別コメントにある

   新しい形式の文字列定数
   C#での@文字列定数
   数値の'による桁区切り

 については、対応してなくても関数一覧が誤動作する可能性は低いように思う
のと、あと、先に対応が必要なのは「ファイルタイプ別の設定・デザイン」の
「文字定数」や「数値」の方になりそうな気がします。そっちが対応したらって
ことでもいいかなぁという気がします。

 とりあえずそれは保留させていただきます。

 対応するにしても、文字列定数中の改行文字については難しいかもしれません。

[ ]
RE:08180 関数一覧に出てこない関数があるNo.08181
colder さん 14/01/30 18:17
 
colderです。

>   新しい形式の文字列定数
>   C#での@文字列定数
>   数値の'による桁区切り
>
> については、対応してなくても関数一覧が誤動作する可能性は低いように思う
>のと、あと、先に対応が必要なのは「ファイルタイプ別の設定・デザイン」の
>「文字定数」や「数値」の方になりそうな気がします。そっちが対応したらって
そうですね。これは関数一覧ではなく、強調定義の話です。

強引に関数一覧が誤動作する例を作れなくもないが。
int func(int x = 1'000) // デフォルト引数に使うとおかしくなる
{
  return x;
}

[ ]
RE:08181 関数一覧に出てこない関数があるNo.08182
秀まるお さん 14/01/30 18:25
 
 そもそも現状の関数一覧自体が100%の精度で動く物じゃない(ちゃんとコンパ
イルして処理してる訳じゃない)ので、とりあえず誤動作する例があっても発生
頻度がきわめて少なそうなら対応不可ということでお願いしたいです。

 それと、あらかじめ宣言してしまうと、

 [[...]]

 のパターンで、中にコメントがあるのも対応不可ってことにしてしまおうと思
います。

 [[..../*...*/  ]]

 [[....//....
]]

 とか。"[["と"]]"の間に改行があるのもダメってことにします。
 (たぶんそういう書き方しないと思うし)

[ ]
RE:08182 関数一覧に出てこない関数があるNo.08185
colder さん 14/01/31 00:36
 
colderです

自作のプログラムを見直してみたらもっと簡単なところで関数一覧に出ない関数があ
るのを発見してしまいました。

・関数テンプレートの明示的な特殊化
template<class T> int func() // こちらは出る
{
  return 0;
}
template<> int func<int>() // これが出ない
{
  return 1;
}

[ ]
RE:08185 関数一覧に出てこない関数があるNo.08188
秀まるお さん 14/01/31 09:02
 
 テンプレートって物は一応知っててそこそこテストもしてたとは思うんですが、
特殊化ってのは知らなくて、テストもしてませんでした。

 今さらながら、そんな難しいルールがあることを勉強してしまいました。

 対応するとなると、テンプレートを表す'<'と'>'が大小比較の記号と違う扱い
にするためのルールが必要なので、その辺の実装が難しいかもしれませんが、な
んとか誤動作しないようなルール作りをしてみます。たぶん"template"ってキー
ワードがあることをうまく判定に使わないとダメなんだと思いますけども。

 とりあえず、"template"ってキーワードが現れたら、";"または"{"または"}"
が出現するまでは"<"と">"はテンプレート用と解釈するようにしたらいいのかな
ぁと思います。もしこの辺のルール作りでも何かご意見ありましたらお願いしま
す。

[ ]
RE:08188 関数一覧に出てこない関数があるNo.08189
秀まるお さん 14/01/31 09:09
 
>  とりあえず、"template"ってキーワードが現れたら、";"または"{"または"}"
> が出現するまでは"<"と">"はテンプレート用と解釈するようにしたらいいのかな
> ぁと思います。もしこの辺のルール作りでも何かご意見ありましたらお願いしま
> す。

 あと、'<'と'>'が同一行内にセットで存在していることも条件にしてしまおう
と思います。

[ ]
RE:08179 関数一覧に出てこない関数があるNo.08192
秀丸担当 さん 14/01/31 17:05
 

C言語系の文字列リテラルについてのご指摘ありがとうございます。
文字列リテラルについて、perlやrubyについては凝ったことをしているところも
あるのですが、C言語系については実はあまり凝っていなくて、普通のCですら、
複数行にわたる文字列は扱っていなかったりします。
複数行は#ifdefの内部情報の都合もあって大変なのですが、一行内であれば比較
的簡単にできると思うので、今後の課題にさせていただきます。

[ ]
RE:08189 関数一覧に出てこない関数があるNo.08203
colder さん 14/02/07 13:21
 
colderです

秀丸ver8.40β4試してみたところ。
例外指定とdecltypeを使って定義されている関数が表示されないようです。
//throw()を使ったときも表示されない
template <class T, class U> auto func(const T& x, const U& y) noexcept(noexc
ept(x+y)) -> decltype(x+y)
{
  return x+y;
}
あまりに複雑なケースで表示出来ないケースが出てくるのはしょうがないですが、
C++に関数の戻り値の型を後に書く構文が追加されたのは、decltypeを使えるように
することが主要な理由なので、これは表示されて欲しいです。

[ ]
RE:08203 関数一覧に出てこない関数があるNo.08204
秀まるお さん 14/02/07 14:23
 
 毎度詳しい情報ありがとうございます。

 調べてみたら、noexceptやthrowをスキップする用の処理が、Javaの場合の
"throws"をスキップする処理と共通になっていて、そこでおかしな判定になって
まってました。

 Javaでのthrowsだけは別の判定ロジックにして、noexceptとthrowは同じ処理
でうまくそこだけ("noexcept(...)"または"throw(...)"の部分だけ)無視する
ように修正させていただきます。

[ ]