ページ 11

呼び出し元でreturnさせるような関数

Posted: 2010年1月16日(土) 20:36
by あらたし
こんばんは。
質問させて下さい。

関数を作りたいと思っています。
関数の内容は、関数を呼び出したら、呼び出し元がreturnするような関数です。
つまり、

int main()
{
return 0;
}

を、

void func()
{
// something..
}
int main()
{
func();
}

のように書き換えられないか、ということです。

Re:呼び出し元でreturnさせるような関数

Posted: 2010年1月16日(土) 20:59
by バグ
こういう事かな?
int func()
{
    // something..
    return 0;
}

int main()
{
    return func();
}

Re:呼び出し元でreturnさせるような関数

Posted: 2010年1月16日(土) 21:46
by あらたし
ありがとうございます。
しかし、そうではなく、mainの中のreturnを取り除きたいのです。
(先のfuncの返り値がvoid型になっていたのはミスです。)

Re:呼び出し元でreturnさせるような関数

Posted: 2010年1月16日(土) 22:13
by Dixq (管理人)
> mainの中のreturnを取り除きたいのです。

取り除けないです。
main関数はかならず帰り値を持つ必要があります。
ただし、

main(){
}



void main(){
}

でも実行できることは出来ますが、正しくないとされています。

どうしてもreturn無しに、関数を呼び出した行の次で関数を終えたいなら


main(){

func();
goto ex;

//(1)
//(2)
//(3)
//(4)
//(5)
ex:
//何か
}

でしょうが、完全に無意味なプログラムになります。

> 関数の内容は、関数を呼び出したら、呼び出し元がreturnするような関数です。

マルチスレッドで動いている場合を想定されているのでしょうか?
呼び出し元は呼び出し先の処理が終わるまで処理が進みません。

Re:呼び出し元でreturnさせるような関数

Posted: 2010年1月16日(土) 22:21
by softya
>ありがとうございます。
>しかし、そうではなく、mainの中のreturnを取り除きたいのです。
>(先のfuncの返り値がvoid型になっていたのはミスです。)

main()のreturnは取り除けません。
関数は必ず暗黙か明示的なreturnが必要で、戻り値のある関数は必ず明示的なreturnが必要です。

main()→func()
と呼び出したら必ず
func()→main()
に戻らないといけません。

Re:呼び出し元でreturnさせるような関数

Posted: 2010年1月16日(土) 22:24
by box
func()の中でexit()すれば?

Re:呼び出し元でreturnさせるような関数

Posted: 2010年1月16日(土) 23:06
by たかぎ
> func()の中でexit()すれば?

これしかないでしょうね。
C++であれば、std::set_terminateでstd::exitを呼び出す関数を登録しておいて、funcから例外を送出するというのもひとつの手です。

Re:呼び出し元でreturnさせるような関数

Posted: 2010年1月16日(土) 23:24
by softya
> func()の中でexit()すれば?
これがfunc()の中でプログラムを抜けたいと言う意味なら正しいと思いますが。

>mainの中のreturnを取り除きたいのです。
return文を書きたくないと言う意味なら、必ずエラーが出ることになるので避けれません。
って答になりますが、求めていることがいまいち分からないんですよね。

Re:呼び出し元でreturnさせるような関数

Posted: 2010年1月16日(土) 23:26
by たかぎ
> return文を書きたくないと言う意味なら、必ずエラーが出ることになるので避けれません。

エラーは出ないと思います。

Re:呼び出し元でreturnさせるような関数

Posted: 2010年1月16日(土) 23:57
by softya
>エラーは出ないと思います。

あっ勘違いしてました。すいません。
そうですね。Cはエラーにならないんですよね。
LINTでわざわざ引っ掛けたのを思い出しました。

Re:呼び出し元でreturnさせるような関数

Posted: 2010年1月17日(日) 00:17
by たかぎ
> そうですね。Cはエラーにならないんですよね。

C++でもエラーになりません。

Re:呼び出し元でreturnさせるような関数

Posted: 2010年1月17日(日) 00:24
by softya
>C++でもエラーになりません。

エラーになる言語としては、C#とかだとエラーになります。

Re:呼び出し元でreturnさせるような関数

Posted: 2010年1月17日(日) 02:21
by あらたし
たくさんの回答ありがとうございます。
“まぁ無理”と言うことですね。
別の方法を取ります。
ありがとうございました。

Re:呼び出し元でreturnさせるような関数

Posted: 2010年1月17日(日) 02:24
by Dixq (管理人)
無理というか、CやC++言語は完成された言語ですから、やりたい事は99.9%出来るはずです。
出来ないなら、使い方を間違っているか、知らないか、そもそもプログラム的な考え方にマッチしないかなどだと思います。
現在あらたしさんがやろうと思っている処理の具体的な内容が解りませんが、
その内容をはっきりさせれば、これ以外にもっと簡単に適切に解決する方法があるはずだと思いますよ。

Re:呼び出し元でreturnさせるような関数

Posted: 2010年1月17日(日) 05:57
by box
> “まぁ無理”と言うことですね。

そうじゃなくて、本当は何をしたいのかが
うまく伝わっていないだけ。

Re:呼び出し元でreturnさせるような関数

Posted: 2010年1月17日(日) 08:51
by たかぎ
> 関数の内容は、関数を呼び出したら、呼び出し元がreturnするような関数です。

これを字面通りに解釈すると、呼び出し元はmainとは限りませんね。
その場合、処理系に依存せずに実現することは無理です。

処理系を特定すれば、保存されている戻り先アドレスを書き換えることで実現可能です。
戻り先アドレスは、スタックに保存されていることもあれば、汎用レジスタ等に保存されていることもあります。また、スタックの場合でも、コーリングコンベンションをよく調べなければ、具体的にどこに保存されるのかわからないと思います。
典型的には...

↑アドレス上位
仮引数
戻り先アドレス
フレームポインタ
自動変数
↓アドレス下位

のようになります。
この場合であれば、
void func(void)
{
  void ** volatile dummy;
  *(&dummy + 2) = *(*(&dummy + 1)  + 2);
}
のような感じで実現できるかもしれません。
検証していないので動くかどうか知りませんし、あらたしさんの環境に通用するかどうかも知りません。

Re:呼び出し元でreturnさせるような関数

Posted: 2010年1月17日(日) 09:38
by dic
なんでそんな子供みたいなこと言うの
ゲームができて動けばいいレベルでしょうに

Re:呼び出し元でreturnさせるような関数

Posted: 2010年1月17日(日) 11:12
by あらたし
>これを字面通りに解釈すると、呼び出し元はmainとは限りませんね。
mainと書いたのが混乱を招いたのですね。
すいませんでした。


>その場合、処理系に依存せずに実現することは無理です。
そうですか。残念です。


たかぎさんの実現方法に関して、おっしゃることは何となく分かるのですが、実装がすごいことになりそうですね。
さすがにそこまで突っ込むのは気が引けてしまいます。
ですが、そういうこともできるということを知ることができて嬉しいです。
ありがとうございます。

Re:呼び出し元でreturnさせるような関数

Posted: 2010年1月17日(日) 11:20
by Ma
dicさん、誰に言っているのでしょうか?(というかその発言は荒らしに見えます。)
私にはみんな真剣に答えているように見えます。 

ともかく、今回の件で意思疎通ができていなかったのは、質問者の質問が具体的ではなかったか、情報や例が足りなかったのが原因だとおもいます。
この件は、全面的に box さんと Dixq さんに同意です。(質問がうまく伝わっていない点で)

それに、ちょっとあいまいだった質問にたかぎさんやsoftyaさんが何を言おうとしているのか
真剣に考えて答えてくれています。

>しかし、そうではなく、mainの中のreturnを取り除きたいのです。
このへんから、なんとなく言っていることが分かってきたかな・・ってぐらいでした。

もし、あらたしさんがまだ見ているのであれば、
これからは質問をより具体的に表現してくれることをお願いしたいです。 画像

Re:呼び出し元でreturnさせるような関数

Posted: 2010年1月17日(日) 11:46
by softya
相変わらずイマイチ何をしたいか分から無いんですが、
setjmp/longjmp
で解決出来る問題かも知れません。
http://www.nurs.or.jp/~sug/soft/super/longjmp.htm
ただ、スタックの働きとか良く分かっていないと
http://tiki.is.os-omicron.org/tiki.cgi? ... %2Flongjmp
のような問題を引き起こします。
まぁ、longjmp自体エラー処理用というか例外処理用的なものですので、日常的に使うのはどうかと思いますが。
普通こんなものを使わなくても大体はプログラムアルゴリズムで解決出来る問題ですので、アルゴリズムをちゃんと考えた方が良いとは思います。