C言語なら俺に聞け 155
レス数が1000を超えています。これ以上書き込みはできません。
>>951
一応は >>949 も未定義だよ。
呼出規約が cdecl だったら余計な引数は捨てられるだけで問題にならないとは思うけど。
余計な引数を渡すのとは逆に必要な引数を渡さないという例も書けるから、
より危険性がわかりやすいかな。
https://wandbox.org/permlink/1F876xK6UZ4wFjAA
余談だけど関数定義は宣言も兼ねるというルールにおいて、
K&R スタイルの関数定義はプロトタイプを持たない宣言でもあるという扱いだから
別途プロトタイプ宣言をする分にはエラーとして検出される。
https://wandbox.org/permlink/4n574f4R9yq0BzUj >>952
> 余計な引数を渡すのとは逆に必要な引数を渡さないという例も書けるから、
たしかにその通りだな。
>>949 のコード例に気をとられて
もとの議論の内容を忘れてたw
thx >>955
普通はする。 すべきだ。 というのがどれほどあてになるか。
普通はすることを (うっかり) しなかったら (エラーとして検出されずに) 通ってしまうってのは
K&R スタイルの関数定義はイケてないねって話。 K&R スタイルでなくともファイルを分割すると宣言と定義の矛盾が検出されなかったりもする。
// foo.c
void foo(int x) {
}
// foo.h
void foo(void);
// main.c
#include "foo.h"
int main(void) {
foo();
}
このとき foo.c をコンパイルするだけなら foo.h は不要だが
foo.c で foo.h をインクルードしておかないと間違いは検出できない。 >>958
大抵の処理系ではリンクエラーにならないよ
C言語だとコンパイル後は引数の情報は無くなっちゃうから 実行時にスタック壊れたり
hangupしたりするんです? >>958
C のオブジェクトファイルは名前しか保存しておらず、
型はヘッダファイルでやりとりするというのが伝統的なデザイン。
だからそれを一致させるのはプログラマの責任。
現代の実装技術なら検出できないことはないはずなんだが、
検出しないのは色々な都合があるんだろう。
>>960
cdecl や fastcall なら関数を呼び出すだけならスタックの整合性が壊れることはないと思うんだけど、
実引数と仮引数がまともに対応付けられていないわけだから
仮引数の読み書き (特に書き込んだとき) には壊れる可能性が高いんじゃないかな。 > 現代の実装技術なら検出できないことはないはずなんだが、
ちゃんとやってるよ
外部参照名の長さの上限を増やすという
後方互換性を損なわない賢いやり方で
それの恩恵を有り難く頂戴しているのがC++ 意味わからん
マンダリングしてるC処理系なんてあったっけ?
別にオブジェクトコードに含ませなくてもデバッグ情報に含ませといてチェックするとかでも良いと思うけどね >>963
32bitWindows向けのstdcallは引数等で使うスタックサイズを名前の後ろに付け加える 本人が間違ってる分には無視すれば良いだけだが
初心者スレで嘘を撒き散らすのは良くないな volatileオブジェクトへのアクセスは副作用を生じるというのを見たことがあるのですが
この場合の副作用とは具体的にはどういう事象のことを言っているのでしょうか? >>968
レジスタなどにアクセスする際に最適化で誤動作しないようにvolatileを付けるのかなと思ったのですが、
逆にvolatileを付けることによる不都合(副作用)って何かあるのでしょうか
それとも最適化されないことを副作用と読んでいるのでしょうか
>>969
最適化しないことによる処理時間増加でしょうか 最適化によって、本来は必要な処理がコンパイラによって省かれてしまうとか コンパイラの判断によって、一部のコードが生成されないとか >>970
プログラミングの世界の副作用とは、不都合とかそんな意味ではなくて、内部状態が変更されるとか、外に何らかの影響を与えるとかそんな意味だよ。
例えばisalpha関数は文字の判定をするだけだけど、printfはコンソールに文字を出力する。
前者は副作用なし、後者は副作用ありだね。
volatileの件はそれが書かれた前後のコンテキストが分からないから何を指してるのか何とも分からんけど、たぶん、>>968に書かれてるように、外部デバイスへの作用のことを指してるんじゃないかな >>970
副作用 (プログラム)
https://ja.wikipedia.org/wiki/%E5%89%AF%E4%BD%9C%E7%94%A8_(%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0)
> プログラミングにおける副作用(ふくさよう)とは、ある機能がコンピュータの(論理的な)状態を変化させ、それ以降で得られる結果に影響を与えることをいう。
C言語における定義はこんな感じ。
http://kikakurui.com/x3/X3010-2003-01.html#13
> ボラタイルオブジェクトへのアクセス,オブジェクトの変更,ファイルの変更,又はこれらのいずれか
> の操作を行う関数の呼出しは,すべて副作用(side effect)と呼び(11),実行環境の状態に変化を生じる。 回答ありがとうございました
組み込みの資料か何かでvolatileの副作用についての記述があり質問させていただきました
副作用の意味がいまいち分かってないみたいなので勉強します int main(double a, double b)
{
printf("main");
} (void)と(int, char**)以外は処理系定義
コンパイラが対応していれば適格
対応していなければ未定義 crtstartupのお仕事だからコンパイラほぼ関係ないな
大抵の実用リンカは差し替えできるでしょ 数値リテラル「0」の型は何ですか?
int* p = 0; // これはOK
int* p = (int)0; // 明示的にint型にしてから渡すと「int型はint*型に変換できません」とエラー。ということは、この 0 はint型以外?
int* p = (unsigned int)0; // これもエラーで無理。
printf("%zu", sizeof(0)); // 0の型のサイズを調べると4byteと表示される。
この数値リテラルの「0」の型は何ですか?
ちなみに、まだC言語環境を構築してないから、代わりVisualC++を使ってるけど、他の環境でも起きますか? さらに調べると・・・・
キャスト演算子で型を指定した0は、代入の際にint*型へ変換してくれない。
接尾語を付けて型を指定した0は、代入の際にint*型に変換してくれる。
int* p = (long int)0; // NG
int* p = 0L; // OK
int* p = (unsigned int)0; // NG
int* p = 0u; // OK
キャスト演算子で型を指定すると、代入の際の暗黙的な変換が禁止される仕様とかあるんですか? >>980
intだよ
D:\learn>gcc --version
gcc (Rev2, Built by MSYS2 project) 10.1.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
D:\learn>gcc 980.c
D:\learn>gcc 980.c -pedantic -Wall
980.c: In function 'main':
980.c:9:10: warning: unused variable 'p3' [-Wunused-variable]
9 | int* p3 = (unsigned int)0; //
| ^~
980.c:8:10: warning: unused variable 'p2' [-Wunused-variable]
8 | int* p2 = (int)0; // ntintnt*nt
| ^~
980.c:7:10: warning: unused variable 'p1' [-Wunused-variable]
7 | int* p1 = 0; // K
| ^~
-Wallにするとunusedって警告でるけど型の話じゃないね >>981
D:\learn>cl 980.c /W4
Microsoft(R) C/C++ Optimizing Compiler Version 19.27.29111 for x64
Copyright (C) Microsoft Corporation. All rights reserved.
980.c
980.c(8): warning C4047: '初期化中': 間接参照のレベルが 'int *' と 'int' で異なっています。
980.c(9): warning C4189: 'p3': ローカル変数が初期化されましたが、参照されていません
980.c(7): warning C4189: 'p1': ローカル変数が初期化されましたが、参照されていません
980.c(8): warning C4189: 'p2': ローカル変数が初期化されましたが、参照されていません
Microsoft (R) Incremental Linker Version 14.27.29111.0
Copyright (C) Microsoft Corporation. All rights reserved.
/out:980.exe
980.obj
参照されていませんという警告は型の話ではないのでここではスルー
型についての警告が出ている8行目とやらはこれ
> int* p2 = (int)0; // 明示的にint型にしてから渡すと「int型はint*型に変換できません」とエラー。ということは、この 0 はint型以外?
隣の9行目は警告されていない(しかも/W4で)
> int* p3 = (unsigned int)0; // これもエラーで無理。
おそらくclが警告しているのはXXX*とXXXでポインタの間接段数を間違えたんだろうということ
これなら9行目はXXX*とYYYで間接段数の問題ではないので黙っているという説明がつく 0だけは特別にポインタにキャスト可能な仕様なんじゃよ
0がいい 0になろう >>980
0 の型は int だけど、空ポインタ定数 "null pointer constant" なので、すべてのポインタ型への暗黙変換が効く。
http://kikakurui.com/x3/X3010-2003-01.html#39
> 値0をもつ整数定数式又はその定数式を型void *にキャストした式を,空ポインタ定数(null pointer constant)と呼ぶ。
(int)0 になると空ポインタ定数ではなくなるので、ポインタに暗黙変換できなくなり、初期化・代入できなくなる。 >>981
int* p = (long int)0; // NG
int* p = (unsigned int)0; // NG
long, unsigned は、int 型と、数値の範囲が異なる。
int 型しかキャストできないのでは? 0も厳格にはマジックナンバーだが
現実のシステムで0番地なんか普通の変数に使えなくていいから
理に適ってる >>982
むつかしくてわからないのでひらがなでおねがいします
>>985
こんな感じで理解しておけばいいですか?
・整数定数式としての「0」とは、ソースコードに直接書かれた「0」で、評価されて返ってきた「(int)0 ⇒ 0」や「4 - 4 ⇒ 0」などの「0」は整数定数式とは言わない。
・同じ0でも、void*型の「0」や、整数定数式としての「0」だけを空ポインタ定数と呼び、空ポインタ定数は代入の際にポインタ型へ暗黙変換できる。
よって
int* p = (int)0; // 「(int)0」が評価されて返ってきた「0」は整数定数式ではないので空ポインタ定数ではない。だから暗黙変換できずに代入無理。
int* p = 4-4; // 同様に、評価されて返ってきた「0」は整数定数式ではないので空ポインタ定数ではない。だから暗黙変換できずに代入無理。
int* p = 0; // 定数式としての「0」だから代入OK
型と値が一緒の、同じint型の「0」であっても、定数式と返り値とでは、それぞれの持ってる機能が違うということですか? >>990
じーしーしーのばーじょんをかくにんしてから
おまえさんのこーどをくわせてみてるんだよ
せんげんだけしてつかってないへんすうがあるのをけいこくされているけど
それはおまえさんがきにしてるかたのもんだいじゃなさそうだねっていってるの >>991
ひらがなでわかりやすくせつめいしてくださったので
あたまのわるいわたしでもようやくわかりました
ありがとうございます NULL == 0 // true
ちなみに0は8進数な NULL == 0 // true
ちなみに0は8進数なんてことなく10進数なんてことなく16進数なんてこともない いや8進数だよ
0xで始まったら16進数
0で始まったら8進数
こんな関数作って見たらわかるよ
syukudai("210") == 210
syukudai("110") == 110
syukudai("010") == 8
syukudai("0x10") == 16 >>996
> 0で始まったら8進数
なら、敢えて数字リテラルで8進数のゼロを表すなら 00 だろう。
つか8未満の数「値」に8進数ってなんだYO!! このスレッドは1000を超えました。
新しいスレッドを立ててください。
life time: 140日 15時間 37分 31秒 5ちゃんねるの運営はプレミアム会員の皆さまに支えられています。
運営にご協力お願いいたします。
───────────────────
《プレミアム会員の主な特典》
★ 5ちゃんねる専用ブラウザからの広告除去
★ 5ちゃんねるの過去ログを取得
★ 書き込み規制の緩和
───────────────────
会員登録には個人情報は一切必要ありません。
月300円から匿名でご購入いただけます。
▼ プレミアム会員登録はこちら ▼
https://premium.5ch.net/
▼ 浪人ログインはこちら ▼
https://login.5ch.net/login.php レス数が1000を超えています。これ以上書き込みはできません。