質問するログイン新規登録

質問編集履歴

5

追記

2017/08/05 13:09

投稿

strike1217
strike1217

スコア651

title CHANGED
File without changes
body CHANGED
@@ -97,7 +97,18 @@
97
97
 
98
98
  間違いがあったらご指摘ください。
99
99
  他にも方法があれば是非教えてください。
100
+ ```ここに言語を入力
101
+ int main() {
102
+ int (*p)() = set(0);
103
+ int (*r)() = set(1);
100
104
 
105
+ ((void (*)(void))p)();
106
+ printf("%d\n", r(1,40));
107
+ return 0;
108
+ }
109
+ ```
110
+ こちらの方が分かりやすいですかね・・・
111
+
101
112
  「追記2」_________________________________
102
113
  あ、この場合は未定義ではないのかな?
103
114
 

4

追記

2017/08/05 13:08

投稿

strike1217
strike1217

スコア651

title CHANGED
File without changes
body CHANGED
@@ -98,7 +98,7 @@
98
98
  間違いがあったらご指摘ください。
99
99
  他にも方法があれば是非教えてください。
100
100
 
101
- 「追記2」_____________________
101
+ 「追記2」_________________________________
102
102
  あ、この場合は未定義ではないのかな?
103
103
 
104
104
  「型変換されたポインタを関数呼出しに用い,関数の型がポインタが指すものの型と適合しない場合,その動作は未定義とする。 」

3

追記

2017/08/05 12:31

投稿

strike1217
strike1217

スコア651

title CHANGED
File without changes
body CHANGED
@@ -96,4 +96,19 @@
96
96
  これぐらいしか方法がなさそうです。
97
97
 
98
98
  間違いがあったらご指摘ください。
99
- 他にも方法があれば是非教えてください。
99
+ 他にも方法があれば是非教えてください。
100
+
101
+ 「追記2」_____________________
102
+ あ、この場合は未定義ではないのかな?
103
+
104
+ 「型変換されたポインタを関数呼出しに用い,関数の型がポインタが指すものの型と適合しない場合,その動作は未定義とする。 」
105
+
106
+ となっているようなので、**呼び出しの際に元の型へ戻しておけば動作は未定義ではない**
107
+ ということだと思います。
108
+
109
+ 型を別のものにキャストして呼び出した場合の話なので、
110
+
111
+ **とある型 → 別の型にキャスト → 元の型にキャスト → 呼び出し** なら大丈夫!!
112
+ **とある型 → 別の型にキャスト → 呼び出し** これはダメ!!
113
+
114
+ という事ですかな?

2

追記

2017/08/05 12:30

投稿

strike1217
strike1217

スコア651

title CHANGED
File without changes
body CHANGED
@@ -77,11 +77,11 @@
77
77
  if (c)
78
78
  return func;
79
79
  else
80
- return (int (*)(void))funcs;
80
+ return (int (*)(void))funcs; //一度キャストしておく
81
81
  }
82
82
 
83
83
  int main() {
84
- void (*p)() = (void (*)(void))set(0);
84
+ void (*p)() = (void (*)(void))set(0); // キャストして元に戻す
85
85
  int (*r)() = set(1);
86
86
 
87
87
  p();

1

追記

2017/08/05 12:18

投稿

strike1217
strike1217

スコア651

title CHANGED
File without changes
body CHANGED
@@ -56,4 +56,44 @@
56
56
 
57
57
  どなたか教えて下さい。
58
58
 
59
- 実験環境は、Windows 64bit visual studio cl オプションなし です。
59
+ 実験環境は、Windows 64bit visual studio cl オプションなし です。
60
+
61
+ 「追記」___________________________
62
+ Saitoさんの回答とコメントを元に作ってみました。
63
+ こんな感じですかね・・・・
64
+
65
+ ```C
66
+ #include<stdio.h>
67
+
68
+ int func(int a, int b) {
69
+ return a + b;
70
+ }
71
+
72
+ void funcs(void) {
73
+ printf("Hello in funcs\n");
74
+ }
75
+
76
+ int (*set(int c))() {
77
+ if (c)
78
+ return func;
79
+ else
80
+ return (int (*)(void))funcs;
81
+ }
82
+
83
+ int main() {
84
+ void (*p)() = (void (*)(void))set(0);
85
+ int (*r)() = set(1);
86
+
87
+ p();
88
+ printf("%d\n", r(1,40));
89
+ return 0;
90
+ }
91
+ ```
92
+
93
+ Warning, Error共になく、正常に動作しています。
94
+ maisumakunさんの回答を見ると、**未定義とされている**ので怖いのですが・・・・
95
+
96
+ これぐらいしか方法がなさそうです。
97
+
98
+ 間違いがあったらご指摘ください。
99
+ 他にも方法があれば是非教えてください。