[解決済み】このC関数は常にfalseを返すべきですが、そうではありません。
質問
昔、あるフォーラムで興味深い質問を偶然見つけたので、その答えを知りたいのです。
次のC関数を考えてみましょう。
f1.c
#include <stdbool.h>
bool f1()
{
int var1 = 1000;
int var2 = 2000;
int var3 = var1 + var2;
return (var3 == 0) ? true : false;
}
これは常に
false
というのは
var3 == 3000
. その
main
関数は次のようになります。
main.c
#include <stdio.h>
#include <stdbool.h>
int main()
{
printf( f1() == true ? "true\n" : "false\n");
if( f1() )
{
printf("executed\n");
}
return 0;
}
以降
f1()
は常に
false
であるならば、このプログラムは1つの
虚偽
を画面に表示します。しかし、コンパイルして実行した結果
実行
も表示されます。
$ gcc main.c f1.c -o test
$ ./test
false
executed
なぜでしょうか?このコードには何か未定義の動作があるのでしょうか?
注:コンパイル時に
gcc (Ubuntu 4.9.2-10ubuntu13) 4.9.2
.
解決方法は?
他の回答にもあるように、問題はあなたが
gcc
で、コンパイラオプションが設定されていない場合。この場合、デフォルトは "gnu90" と呼ばれるもので、1990年に撤回された古いC90標準の非標準の実装となります。
古いC90規格では、C言語には大きな欠陥がありました。関数を使う前にプロトタイプを宣言しないと、関数のデフォルトが
int func ()
(ここで
( )
は任意のパラメータを受け入れるという意味です。) これにより、関数の呼び出し規則が変更されます。
func
しかし、実際の関数定義は変更されません。のサイズが小さくなっているので
bool
と
int
が異なる場合、あなたのコードは、関数が呼ばれたときに未定義の動作を呼び出します。
この危険な無意味な動作は、1999年にC99規格が発表されたことで修正された。暗黙の関数宣言は禁止されたのだ。
残念ながら、バージョン5.x.xまでのGCCは、デフォルトで古いC標準をまだ使っています。あなたのコードを標準C以外としてコンパイルしたい理由はおそらくないでしょう。ですから、あなたのコードを25年以上前の非標準のGNUのがらくたの代わりに、現代のCコードとしてコンパイルするよう、GCCに明示的に指示する必要があるのです。
常にasでコンパイルすることで、問題を解決します。
gcc -std=c11 -pedantic-errors -Wall -Wextra
-
-std=c11
は、(現在の) C 標準規格 (非公式には C11 として知られている) に従ってコンパイルするよう、半ば強制するように指示します。 -
-pedantic-errors
は、上記のことを全面的に実行し、C標準に違反する不正なコードを書くとコンパイラーエラーを出すように指示します。 -
-Wall
は、あった方がいいような追加の警告を出すという意味です。 -
-Wextra
は、あると便利な他の警告をいくつか教えてください、という意味です。
関連
-
[解決済み】エラー:cの入力の最後に期待される宣言またはステートメント
-
[解決済み】ISO C90では、C言語での宣言とコードの混在が禁止されています。
-
[解決済み】C言語におけるファイルスコープでの可変長配列の変更
-
[解決済み】 error: too few arguments to function `printDay' (C言語)
-
[解決済み】C言語で入力が整数型かどうかチェックする
-
[解決済み] C: エラー: ';'トークンの前に ')' があると予想される
-
[解決済み】0LLや0x0ULの意味は何ですか?
-
[解決済み】エラー:呼び出されたオブジェクトは、関数または関数ポインタではない
-
[解決済み] CとC++でmain()は何を返すべきですか?
-
[解決済み】なぜ常にコンパイラの警告を有効にしなければならないのですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] c - 初期化がキャストなしでポインタから整数を作る、さらに2つのコンパイラーエラー
-
[解決済み】変数の警告が設定されているが使用されていない
-
[解決済み】単項演算子「*」の型が無効(「int」がある)C言語でのエラー
-
[解決済み】組み込み関数「malloc」の暗黙の宣言の非互換性
-
[解決済み] (.text+0x20): `main'への未定義の参照と関数への未定義の参照
-
[解決済み】 strcpyとstrdupの比較
-
[解決済み】 switch case: error: case label does not reduce to an integer constant
-
[解決済み】「複数の定義」「最初に定義されたのはここです」エラーについて
-
[解決済み】エラー:不明な型名'bool'
-
[解決済み】C言語のフォーマット文字列でデータ引数が使用されない [重複]。