競技プログラミング用 知識集積所
エラー
最終更新:
sport_programming
-
view
雑な説明
プログラムを書いたときに、うまく動かないことがある。
そのときに、エラーを表示してくれたり、してくれなかったり、をヒントにどうにか修正しなければならない。
そのための知識集。
難度を問わず掲載(C++23のgccでの情報のみ)。
そのときに、エラーを表示してくれたり、してくれなかったり、をヒントにどうにか修正しなければならない。
そのための知識集。
難度を問わず掲載(C++23のgccでの情報のみ)。
コンパイルエラー CE
AtCoderの場合は、提出でCEを出してもペナルティにならない。
エラーメッセージの見方
標準エラー出力の最初に
Main.cpp: In function ‘int main()’: Main.cpp:18:3: error:
と書いてあった場合、main()関数内、全体で18行目の3文字目にエラーがある。
多くの場合はここに何か書き忘れているか、余計なことが書いてある。
その行の先頭にエラーがあると表示されている場合は、本当にエラーしているのは1つ前の行の末尾であることもある。
多くの場合はここに何か書き忘れているか、余計なことが書いてある。
その行の先頭にエラーがあると表示されている場合は、本当にエラーしているのは1つ前の行の末尾であることもある。
たくさんエラーが出た場合は、まずは最初のエラーを解決する(超重要)。
というのも、2つ目以降のエラーは1つ目のエラーの影響で発生しているだけということも多く、その場合はもちろん2つ目以降のエラーの原因を探すのは無駄な努力であるため。
というのも、2つ目以降のエラーは1つ目のエラーの影響で発生しているだけということも多く、その場合はもちろん2つ目以降のエラーの原因を探すのは無駄な努力であるため。
また、1つ目のエラー場所がMain.cppでない場合、Main.cppでの場所が初めて出てくる場所を探す。
ライブラリの使い方が正しくなかったせいでライブラリ内でエラーが発生した場合、
ライブラリの使い方が正しくなかったせいでライブラリ内でエラーが発生した場合、
エラーしたライブラリとその場所 ↑を呼び出したライブラリとその場所 ↑を呼び出したライブラリとその場所 ↑を呼び出したライブラリとその場所 ↑を呼び出したMain.cppの場所
のような表示になるため。
エラーとワーニング
標準エラー出力のメッセージが
Main.cpp:18:3: error:
ではなく
Main.cpp:18:3: warning:
であることがある。
warningは「このまま実行しようと思えばできるけど、なんか変じゃない? 大丈夫?」という類のもの。
内容を確認して、大丈夫そうなら無視してもよい。
とはいえ、毎回表示されるとエラーメッセージ確認時に邪魔ではある……。
warningは「このまま実行しようと思えばできるけど、なんか変じゃない? 大丈夫?」という類のもの。
内容を確認して、大丈夫そうなら無視してもよい。
とはいえ、毎回表示されるとエラーメッセージ確認時に邪魔ではある……。
よくあるコンパイルエラーメッセージ(宣言・識別子が見つからない系)
未宣言の変数を使っている場合
Main.cpp:18:3: error: ‘a’ was not declared in this scope
18 | a = 0;
| ^
not declared(宣言されていない)と書かれている場合、変数の宣言がされていない。
^で示された部分に未宣言の変数があるし、エラーメッセージにも書かれている。
原因は、単純に宣言忘れの場合もあるし、変数名のタイポである場合もある。
あとは、スコープのミスということもある。
また、他のミスが文法上変数と解釈される形になってこのエラーが表示されている場合もある。
^で示された部分に未宣言の変数があるし、エラーメッセージにも書かれている。
原因は、単純に宣言忘れの場合もあるし、変数名のタイポである場合もある。
あとは、スコープのミスということもある。
また、他のミスが文法上変数と解釈される形になってこのエラーが表示されている場合もある。
未宣言の型を使っている場合
Main.cpp:4:1: error: ‘Foo’ does not name a type
4 | Foo x;
| ^~~
does not name(名付けていない)と書かれている場合、まだ存在しない型を使おうとしている。
原因は、型を作る前に使ってしまった場合もあるし、タイポということもある。
ただし、変な型を使った場合でも、未宣言の変数と解釈されて、1つ上の項目のエラーが出る場合もある。
原因は、型を作る前に使ってしまった場合もあるし、タイポということもある。
ただし、変な型を使った場合でも、未宣言の変数と解釈されて、1つ上の項目のエラーが出る場合もある。
stdの何かの名前を間違えた場合
Main.cpp:13:8: error: ‘a’ is not a member of ‘std’
13 | std::a;
| ^
not a member of ‘std’(stdのメンバーではない)と書かれている場合、std::のうしろに変な名前を書いてしまっている。
using namespace std; を使って std:: の記述を略している場合は普通は発生しない。
using namespace std; を使って std:: の記述を略している場合は普通は発生しない。
以下のようにstdではなく自作の何かで類似のエラーが出た場合、
Main.cpp:15:9: error: ‘X’ is not a member of ‘Hoge’
15 | Hoge::X a;
|
そもそものHogeの方の実装ミスや記述の可能性もあるため、そちらも確認する。
よくあるコンパイルエラーメッセージ(関数呼び出し系)
引数の型がおかしい場合
Main.cpp:15:6: error: no matching function for call to ‘max(int&, double&)’
15 | max(n,d);
| ~~~^~~~~
no matching function(合う関数がない)と書かれている場合、その引数を受け取れる関数がない。
この例ではint型のnとdouble型のdをmax()※に渡そうとしているが、この関数は同じ型の変数2つを渡すのが正しいため、エラーとなってしまった。
型変換※などで適切な型で渡すように修正する。
そのエラーメッセージの下に note: candidate という表示があり、正しい引数の型が表示されているが、見にくい場合も多い。
実際のミスが個数の間違いでも、別の型で渡せばその個数で動く同名の関数があったためにこっちのエラーが出ていることもある。
この例ではint型のnとdouble型のdをmax()※に渡そうとしているが、この関数は同じ型の変数2つを渡すのが正しいため、エラーとなってしまった。
型変換※などで適切な型で渡すように修正する。
そのエラーメッセージの下に note: candidate という表示があり、正しい引数の型が表示されているが、見にくい場合も多い。
実際のミスが個数の間違いでも、別の型で渡せばその個数で動く同名の関数があったためにこっちのエラーが出ていることもある。
逆に、合う関数が複数ある状況ではambiguous(曖昧な)と書かれる場合もある。
引数の個数がおかしい場合
Main.cpp:19:4: error: too few arguments to function ‘void f(int, int)’
19 | f(n);
| ~^~~
Main.cpp:19:4: error: too many arguments to function ‘void f(int, int)’
19 | f(l,m,n);
| ~^~~~~~~
too few arguments(引数が少なすぎる)、too many arguments(引数が多すぎる)と書かれている場合、引数の個数を間違えている。
この例では、int型の引数2つを取る関数fに、引数を1つだけ、あるいは3つも渡してしまい、エラーとなってしまった。
渡すべき引数の個数を再確認して修正する。
この例では、int型の引数2つを取る関数fに、引数を1つだけ、あるいは3つも渡してしまい、エラーとなってしまった。
渡すべき引数の個数を再確認して修正する。
型の暗黙変換に失敗した場合
Main.cpp:17:5: error: could not convert ‘n’ from ‘int’ to ‘std::string’ {aka ‘std::__cxx11::basic_string<char>’}
17 | f(n);
| ^
| |
| int
could not convert(変換できない)と書かれている場合、型の暗黙変換に失敗している。
例えばlong long型を受け取る関数にint型を渡すと、自動的にlong long型に変換して動作してくれる。
しかし、この例ではstring型を受け取る関数にint型を渡していて、さすがに型変換ができなかったためエラーとなってしまった。
修正は、引数の型がおかしい場合と同じ。
例えばlong long型を受け取る関数にint型を渡すと、自動的にlong long型に変換して動作してくれる。
しかし、この例ではstring型を受け取る関数にint型を渡していて、さすがに型変換ができなかったためエラーとなってしまった。
修正は、引数の型がおかしい場合と同じ。
参照渡しに、変数ではない一時値などを渡してしまった場合
Main.cpp:17:6: error: cannot bind non-const lvalue reference of type ‘int&’ to an rvalue of type ‘int’
17 | f(n+1);
| ~^~
cannot bind(割り当てできない)と書かれている場合、参照渡しで受け取る関数に、一時値などを渡してしまっている。
この例では、fはint&で引数を取るが、n+1は変数そのものではないので、エラーとなってしまった。
一度変数に入れてから渡すか、変更の予定がないなら関数側でconstで受け取るか値渡しにするか、に修正する。
この例では、fはint&で引数を取るが、n+1は変数そのものではないので、エラーとなってしまった。
一度変数に入れてから渡すか、変更の予定がないなら関数側でconstで受け取るか値渡しにするか、に修正する。
よくあるコンパイルエラーメッセージ(構文エラー系)
セミコロンを忘れた場合
Main.cpp:19:3: error: expected ‘,’ or ‘;’ before ‘int’
19 | int b = 0;
| ^~~
expected(期待される)と書かれている場合、何か必要なものを書き忘れている。
この場合、18行目の末のセミコロンを忘れたために、19行目の先頭でエラーしている。
このタイプのエラーでは、^の位置ではなくその直前がエラー場所なので注意。
expectedの後ろに書かれているものを書き足して修正すること。
ただし、コンパイラが自分の書きたいものとは違うコードを想定してメッセージを出している場合もあるので、内容もきちんと確認すること。
この場合、18行目の末のセミコロンを忘れたために、19行目の先頭でエラーしている。
このタイプのエラーでは、^の位置ではなくその直前がエラー場所なので注意。
expectedの後ろに書かれているものを書き足して修正すること。
ただし、コンパイラが自分の書きたいものとは違うコードを想定してメッセージを出している場合もあるので、内容もきちんと確認すること。
括弧の不整合がある場合
Main.cpp:26:12: error: expected ‘}’ at end of input
26 | return 0;
|
上と同じく、expected(期待される)と書かれているので、必要なものを書き忘れている。
ただし、括弧を忘れたその場がエラーしているとは限らない(間違った組み合わせで括弧の対応がとられてしまっている)。
全体をよく見て足りない場所を慎重に探すこと。
VScodeなどを使っている場合、{}の不整合には色付けや自動整形を使ってみるのも手。
ただし、括弧を忘れたその場がエラーしているとは限らない(間違った組み合わせで括弧の対応がとられてしまっている)。
全体をよく見て足りない場所を慎重に探すこと。
VScodeなどを使っている場合、{}の不整合には色付けや自動整形を使ってみるのも手。
また、{}の閉じる方が多い場合のエラーメッセージは以下。
Main.cpp:30:1: error: expected declaration before ‘}’ token
30 | }
| ^
式の書き方が正しくない場合
Main.cpp:20:9: error: expected primary-expression before ‘/’ token
20 | a = b+/c;
| ^
expected primary-expression(基本式が期待される)と書いてある場合、式を書くべきところに式ではない何かを書いてしまっている、または空欄になってしまっている。
タイポ等で変な記述になっているので、よく見直して修正する。
とりあえず疑うのは演算子の前後に変数書き忘れ、関数の引数が空になっている、の2つだが、他の原因のこともある。
タイポ等で変な記述になっているので、よく見直して修正する。
とりあえず疑うのは演算子の前後に変数書き忘れ、関数の引数が空になっている、の2つだが、他の原因のこともある。
よくあるコンパイルエラーメッセージ(型エラー系)
変なメンバにアクセスした
Main.cpp:21:9: error: ‘class std::vector<int>’ has no member named ‘hoge’
21 | s = a.hoge();
| ^~~~
has no member(メンバが存在しない)と書かれている場合、存在しないメンバを利用しようとしている。
この例では、aはvectorというクラスであるが、vectorに.hoge()というメンバーは存在しない。
メンバの名前を間違えている可能性が高く、変数の型(クラス)を間違えている場合もある。
※下の項目と違い、クラスではあるが、APIがおかしい
この例では、aはvectorというクラスであるが、vectorに.hoge()というメンバーは存在しない。
メンバの名前を間違えている可能性が高く、変数の型(クラス)を間違えている場合もある。
※下の項目と違い、クラスではあるが、APIがおかしい
クラスじゃないのにメンバアクセスした
Main.cpp:20:9: error: request for member ‘size’ in ‘n’, which is of non-class type ‘int’
20 | a = n.size();
| ^~~~
request for member(メンバ要求)、which is of non-class type(クラスではない)と書かれている場合、クラスではない(つまりメンバを持たない)変数のメンバを利用しようとしている。
この例では、nはint型であり、クラスではないため、当然.size()などというメンバは存在しない。
変数の型を間違えている可能性が高い。
※上の項目と違い、そもそもクラスでない
この例では、nはint型であり、クラスではないため、当然.size()などというメンバは存在しない。
変数の型を間違えている可能性が高い。
※上の項目と違い、そもそもクラスでない
変な演算子を使った
Main.cpp:21:9: error: no match for ‘operator+’ (operand types are ‘std::vector<int>’ and ‘int’)
21 | b = a + n;
| ~ ^ ~
| | |
| | int
| std::vector<int>
no match for ‘operator+'(+という演算子に適合しない)と書かれている場合、演算子の使い方を誤っている。
(実際には、‘operator+'の+の代わりに今回適合できなかった演算子が書き込まれている)
この場合、vectorであるaとint型であるnを足そうとしたためにエラーとなってしまった。
自分のコードをよく見て、変数の型を確認し、正しい演算子に直すか、正しい変数の型に直すか、などで修正する。
(実際には、‘operator+'の+の代わりに今回適合できなかった演算子が書き込まれている)
この場合、vectorであるaとint型であるnを足そうとしたためにエラーとなってしまった。
自分のコードをよく見て、変数の型を確認し、正しい演算子に直すか、正しい変数の型に直すか、などで修正する。
no match for ‘operator=' の場合には、const※など代入禁止の変数に対して代入しようとしている場合もある。
よくあるコンパイルエラーメッセージ(テンプレート系)
編集中。
よくあるコンパイルエラーメッセージ(リンクエラー系)
編集中。
よくあるコンパイルエラーメッセージ(ライブラリ/ヘッダ系)
編集中。
よくあるコンパイルエラーメッセージ(その他)
全角文字を使った場合
Main.cpp:18:3: error: extended character is not valid in an identifier
18 |
| ^
extended character(拡張文字)というのが全角文字を意味する。
この例では^の位置に全角スペースが入っている。
消して、半角スペースやTABに変えること。
この例では^の位置に全角スペースが入っている。
消して、半角スペースやTABに変えること。
編集中。
実行時エラー
編集中。
よくある実行時エラーメッセージ
編集中。
vectorの範囲外アクセス
編集中。
ゼロ除算
編集中。
論理エラー
編集中。
よくある論理エラー
編集中。