回答編集履歴

2

エラーになる話の追記

2020/08/04 10:03

投稿

raccy
raccy

スコア21739

test CHANGED
@@ -89,3 +89,55 @@
89
89
 
90
90
 
91
91
  なお、`\t`が何かというとことに答えないのは、この質問が、[XY 問題](https://ja.meta.stackoverflow.com/questions/2701)になってしまっているからです。
92
+
93
+
94
+
95
+ ---
96
+
97
+
98
+
99
+ 【追記】
100
+
101
+
102
+
103
+ 例示のCのコードについてエラーになると言われたので、なぜ、エラーになる場合があるのかについて解説します。なお、CやC++の基礎的な知識が前提となりますので、あらかじめご了承ください。
104
+
105
+
106
+
107
+ 例示の**C**のコードを**C++として**コンパイルした場合、コンパイラの種類やバージョン、および、オプションによっては、
108
+
109
+
110
+
111
+ * 問題なくコンパイルできる。
112
+
113
+ * 警告が表示されるがコンパイルできる。
114
+
115
+ * エラーとなりコンパイルできない。
116
+
117
+
118
+
119
+ の3パターンがあらわれます。これは文字列リテラルに関する歴史的経緯とその後のC++の対応によるものです。
120
+
121
+
122
+
123
+ まず、C++はCを拡張した作られた言語ですが、CがそのままC++として必ず動くわけではありません。C++はCの完全上位互換ではなく、Cとは非互換な部分があります。今回はその非互換な部分の一つが現れた結果です。.
124
+
125
+
126
+
127
+ `"abc"`のような文字列リテラルの型は、Cでの`char[N]`です。`N`はそのリテラルの終端null文字を含む大きさになります。しかし、文字列リテラルを構成する各文字を変更することは未定義な動作です。そこで、C++では、文字列リテラルの型は`const char[N]`と`const`修飾子によって保護するようになりました。(Cが作られた当初は、`const`修飾子そのものがなかったため、保護するという作りにしませんでした。その後の互換性から未だに`char[N]`のままです。)
128
+
129
+
130
+
131
+ 賢明な読者の方々であれば、`const`あり型の値を`const`なし型の値に代入することはキャストをしないとできないことはご存じかと思います。つまり、C++では`const char[N]`を`char *`に代入することはできないと言うことです。しかし、Cとの互換性のためにC++03までは特別に文字列リテラルから`char *`へ代入することは許容されていました。C++11になって、そのような例外を認めず、明示的にキャストしない限り認めないとなったのです。
132
+
133
+
134
+
135
+ このことが複雑な事情を産みました。C++03までしか対応していない古いコンパイラであれば問題ありませんが、C++11に対応したコンパイラの場合、仕様を厳密に適用するのか、警告で済ますのか、仕様を無視するのかの選択が生まれ、コンパイルオプションによって選択できるようにしました。そのため、コンパイラの種類、バージョン、および、コンパイルオプションによって、コンパイルができたりできなかったり、警告やエラーが出る出ないも変わってくると言うことです。
136
+
137
+
138
+
139
+ なお、`char s[] = "abc";`と書く場合はC++11以上でも問題ありません。なぜなら、この場合は文字列リテラル部分は配列の初期化子として扱われ、`char s[] = {'a', 'b', 'c', '\0'};`相当の動作になるからです。これも、C/C++をご存じであれば、知っていて当たり前のことですね。
140
+
141
+
142
+
143
+ このようにCとC++は似ているようで、結構な違いあります。自分が書いているコードがCなのか、C++なのか、また、Cとしてコンパイルしているのか、C++としてコンパイルしているのかを正しく区別できないと、C/C++を扱うのは難しいです。特に、Visual StudioのC++コンパイラは、拡張子によってCなのかC++なのか扱いが変わるという動作がデフォルトになっており、さらに混乱することになるでしょう。

1

より正確な表現に変更

2020/08/04 10:03

投稿

raccy
raccy

スコア21739

test CHANGED
@@ -10,7 +10,7 @@
10
10
 
11
11
 
12
12
 
13
- **MeCabを使のに`strtok`は必要ありません。**MeCab内で各ノードはすでに分割されており、それぞれのノードへアクセスするためのAPI(ライブラリの関数)があります。`strtok`等で再度結果を分割する必要はありません。もし、そのようなことが必要な場合は、正しいAPIを使用していない事になります。
13
+ **MeCabを使って形態素を取り出すのに`strtok`は必要ありません。**MeCab内で各ノードはすでに分割されており、それぞれのノードへアクセスするためのAPI(ライブラリの関数)があります。`strtok`等で再度結果を分割する必要はありません。もし、そのようなことが必要な場合は、正しいAPIを使用していない事になります。
14
14
 
15
15
 
16
16