2ちゃんねる ■掲示板に戻る■ 全部 1- 最新50    

■ このスレッドは過去ログ倉庫に格納されています

C言語なら俺に聞け 155

1 :デフォルトの名無しさん (ワッチョイ 76ba-P5bm):2020/05/10(日) 23:20:27 ID:Z3WQBr9X0.net
!extend:checked:vvvvv:1000:512
(新スレ立ての際上記コマンドを2行書き込んでください)
C言語の話題のみ取り扱います C++の話題はC++スレへ
質問には最低限の情報(ソース/コンパイラ/OS)を付ける
数行で収まらないソースは以下を適当に使ってURLを晒す
https://paiza.io/
https://ideone.com/
http://codepad.org/

C11
http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1570.pdf

C99
http://www.open-std.org/jtc1/sc22/WG14/www/docs/n1256.pdf
http://kikakurui.com/x3/X3010-2003-01.html

C FAQ 日本語訳
http://www.kouno.jp/home/c_faq/

JPCERT C コーディングスタンダード
https://www.jpcert.or.jp/sc-rules/

※前スレ
C言語なら俺に聞け 154
https://mevius.5ch.net/test/read.cgi/tech/1578997950/ VIPQ2_EXTDAT: checked:vvvvv:1000:512:: EXT was configured

952 :はちみつ餃子 :2020/09/19(土) 13:13:28.09 ID:cxOsPIuF0.net
>>951
一応は >>949 も未定義だよ。
呼出規約が cdecl だったら余計な引数は捨てられるだけで問題にならないとは思うけど。

余計な引数を渡すのとは逆に必要な引数を渡さないという例も書けるから、
より危険性がわかりやすいかな。

https://wandbox.org/permlink/1F876xK6UZ4wFjAA

余談だけど関数定義は宣言も兼ねるというルールにおいて、
K&R スタイルの関数定義はプロトタイプを持たない宣言でもあるという扱いだから
別途プロトタイプ宣言をする分にはエラーとして検出される。

https://wandbox.org/permlink/4n574f4R9yq0BzUj

953 :デフォルトの名無しさん :2020/09/19(土) 14:57:40.15 ID:Uw1s41Nc0.net
>>952
> 余計な引数を渡すのとは逆に必要な引数を渡さないという例も書けるから、
たしかにその通りだな。

>>949 のコード例に気をとられて
もとの議論の内容を忘れてたw

thx

954 :デフォルトの名無しさん :2020/09/19(土) 14:57:50.91 ID:Uw1s41Nc0.net
すまんsage

955 :デフォルトの名無しさん :2020/09/21(月) 03:21:46.70 ID:SqQ7e3H60.net
>>952
普通先行宣言をちゃんとするだろ

956 :はちみつ餃子 :2020/09/21(月) 08:57:54.77 ID:sulqQktu0.net
>>955
普通はする。 すべきだ。 というのがどれほどあてになるか。

普通はすることを (うっかり) しなかったら (エラーとして検出されずに) 通ってしまうってのは
K&R スタイルの関数定義はイケてないねって話。

957 :はちみつ餃子 :2020/09/21(月) 08:59:37.43 ID:sulqQktu0.net
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 :デフォルトの名無しさん :2020/09/21(月) 10:49:53.26 ID:M8W5JifWF.net
linkエラーは?

959 :デフォルトの名無しさん :2020/09/21(月) 11:10:21.40 ID:WONfy98d0.net
>>958
大抵の処理系ではリンクエラーにならないよ
C言語だとコンパイル後は引数の情報は無くなっちゃうから

960 :デフォルトの名無しさん :2020/09/21(月) 11:19:45.80 ID:M8W5JifWF.net
実行時にスタック壊れたり
hangupしたりするんです?

961 :はちみつ餃子 :2020/09/21(月) 12:59:37.93 ID:sulqQktu0.net
>>958
C のオブジェクトファイルは名前しか保存しておらず、
型はヘッダファイルでやりとりするというのが伝統的なデザイン。
だからそれを一致させるのはプログラマの責任。

現代の実装技術なら検出できないことはないはずなんだが、
検出しないのは色々な都合があるんだろう。

>>960
cdecl や fastcall なら関数を呼び出すだけならスタックの整合性が壊れることはないと思うんだけど、
実引数と仮引数がまともに対応付けられていないわけだから
仮引数の読み書き (特に書き込んだとき) には壊れる可能性が高いんじゃないかな。

962 :デフォルトの名無しさん :2020/09/21(月) 17:40:26.50 ID:PNFNM3Vd0.net
> 現代の実装技術なら検出できないことはないはずなんだが、

ちゃんとやってるよ
外部参照名の長さの上限を増やすという
後方互換性を損なわない賢いやり方で

それの恩恵を有り難く頂戴しているのがC++

963 :デフォルトの名無しさん :2020/09/21(月) 20:06:59.96 ID:CAa9Vr4hM.net
意味わからん
マンダリングしてるC処理系なんてあったっけ?
別にオブジェクトコードに含ませなくてもデバッグ情報に含ませといてチェックするとかでも良いと思うけどね

964 :デフォルトの名無しさん :2020/09/21(月) 21:16:44.87 ID:PNFNM3Vd0.net
s/マンダリング/マングリング/g

965 :デフォルトの名無しさん :2020/09/21(月) 21:27:28.62 ID:r8sxqPhqM.net
>>963
32bitWindows向けのstdcallは引数等で使うスタックサイズを名前の後ろに付け加える

966 :デフォルトの名無しさん :2020/09/22(火) 02:46:33.89 ID:EwzeVKsQ0.net
本人が間違ってる分には無視すれば良いだけだが
初心者スレで嘘を撒き散らすのは良くないな

967 :デフォルトの名無しさん :2020/09/22(火) 09:19:28.05 ID:73EWHT9ca.net
volatileオブジェクトへのアクセスは副作用を生じるというのを見たことがあるのですが
この場合の副作用とは具体的にはどういう事象のことを言っているのでしょうか?

968 :デフォルトの名無しさん :2020/09/22(火) 09:29:18.39 ID:GaogVwml0.net
>>967
具体例としては、 volatile なオブジェクトへのポインタを通したアクセスをメモリマップドI/Oと対応させることが多い。
https://ja.wikipedia.org/wiki/%E3%83%A1%E3%83%A2%E3%83%AA%E3%83%9E%E3%83%83%E3%83%97%E3%83%89I/O

969 :デフォルトの名無しさん :2020/09/22(火) 11:37:01.89 ID:duZr+LV8M.net
>>967
遅くなることがあるということかな?

970 :デフォルトの名無しさん :2020/09/22(火) 12:21:55.75 ID:73EWHT9ca.net
>>968
レジスタなどにアクセスする際に最適化で誤動作しないようにvolatileを付けるのかなと思ったのですが、
逆にvolatileを付けることによる不都合(副作用)って何かあるのでしょうか
それとも最適化されないことを副作用と読んでいるのでしょうか

>>969
最適化しないことによる処理時間増加でしょうか

971 :デフォルトの名無しさん :2020/09/22(火) 12:26:59.11 ID:ZRR+59kRa.net
最適化によって、本来は必要な処理がコンパイラによって省かれてしまうとか

972 :デフォルトの名無しさん :2020/09/22(火) 12:28:12.05 ID:ZRR+59kRa.net
コンパイラの判断によって、一部のコードが生成されないとか

973 :デフォルトの名無しさん :2020/09/22(火) 12:48:41.23 ID:fNKq19I/0.net
>>970
プログラミングの世界の副作用とは、不都合とかそんな意味ではなくて、内部状態が変更されるとか、外に何らかの影響を与えるとかそんな意味だよ。

例えばisalpha関数は文字の判定をするだけだけど、printfはコンソールに文字を出力する。
前者は副作用なし、後者は副作用ありだね。

volatileの件はそれが書かれた前後のコンテキストが分からないから何を指してるのか何とも分からんけど、たぶん、>>968に書かれてるように、外部デバイスへの作用のことを指してるんじゃないかな

974 :デフォルトの名無しさん :2020/09/22(火) 13:01:07.61 ID:GaogVwml0.net
>>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),実行環境の状態に変化を生じる。

975 :967 :2020/09/22(火) 17:15:02.44 ID:73EWHT9ca.net
回答ありがとうございました
組み込みの資料か何かでvolatileの副作用についての記述があり質問させていただきました
副作用の意味がいまいち分かってないみたいなので勉強します

976 :デフォルトの名無しさん :2020/09/26(土) 02:24:05.62 ID:AJ59WF/j0.net
int main(double a, double b)
{
printf("main");
}

977 :デフォルトの名無しさん :2020/09/26(土) 02:27:39.44 ID:80lZAyo5a.net
コンパイル通るのかな….

978 :デフォルトの名無しさん :2020/09/26(土) 05:50:57.90 ID:JvTrRG8q0.net
(void)と(int, char**)以外は処理系定義
コンパイラが対応していれば適格
対応していなければ未定義

979 :デフォルトの名無しさん :2020/09/27(日) 13:50:39.37 ID:LQE5yA3hM.net
crtstartupのお仕事だからコンパイラほぼ関係ないな
大抵の実用リンカは差し替えできるでしょ

980 :デフォルトの名無しさん :2020/09/28(月) 07:00:27.18 ID:BXhKM0Xn0.net
数値リテラル「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++を使ってるけど、他の環境でも起きますか?

981 :デフォルトの名無しさん :2020/09/28(月) 07:30:53.01 ID:BXhKM0Xn0.net
さらに調べると・・・・
キャスト演算子で型を指定した0は、代入の際にint*型へ変換してくれない。
接尾語を付けて型を指定した0は、代入の際にint*型に変換してくれる。

int* p = (long int)0; // NG
int* p = 0L; // OK

int* p = (unsigned int)0; // NG
int* p = 0u; // OK

キャスト演算子で型を指定すると、代入の際の暗黙的な変換が禁止される仕様とかあるんですか?

982 :デフォルトの名無しさん :2020/09/28(月) 07:54:15.67 ID:QxfbhGyV0.net
>>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って警告でるけど型の話じゃないね

983 :デフォルトの名無しさん :2020/09/28(月) 08:00:54.96 ID:QxfbhGyV0.net
>>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で間接段数の問題ではないので黙っているという説明がつく

984 :デフォルトの名無しさん :2020/09/28(月) 08:46:00.83 ID:E0ldxkXM0.net
0だけは特別にポインタにキャスト可能な仕様なんじゃよ
0がいい 0になろう

985 :デフォルトの名無しさん :2020/09/28(月) 08:46:40.00 ID:IwymMB/J0.net
>>980
0 の型は int だけど、空ポインタ定数 "null pointer constant" なので、すべてのポインタ型への暗黙変換が効く。
http://kikakurui.com/x3/X3010-2003-01.html#39
> 値0をもつ整数定数式又はその定数式を型void *にキャストした式を,空ポインタ定数(null pointer constant)と呼ぶ。

(int)0 になると空ポインタ定数ではなくなるので、ポインタに暗黙変換できなくなり、初期化・代入できなくなる。

986 :デフォルトの名無しさん :2020/09/28(月) 09:14:55.72 ID:QIpyCS2B0.net
>>981
int* p = (long int)0; // NG
int* p = (unsigned int)0; // NG

long, unsigned は、int 型と、数値の範囲が異なる。
int 型しかキャストできないのでは?

987 :986 :2020/09/28(月) 09:19:20.10 ID:QIpyCS2B0.net
0 アドレスの特別ルールか

988 :デフォルトの名無しさん :2020/09/28(月) 09:26:33.33 ID:QxfbhGyV0.net
0も厳格にはマジックナンバーだが
現実のシステムで0番地なんか普通の変数に使えなくていいから
理に適ってる

989 :デフォルトの名無しさん :2020/09/28(月) 09:47:47.09 ID:IwymMB/J0.net
アドレスは関係ないよ。
http://www.kouno.jp/home/c_faq/c5.html#5

990 :デフォルトの名無しさん :2020/09/28(月) 10:10:46.96 ID:BXhKM0Xn0.net
>>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」であっても、定数式と返り値とでは、それぞれの持ってる機能が違うということですか?

991 :デフォルトの名無しさん :2020/09/28(月) 10:24:28.53 ID:QxfbhGyV0.net
>>990
じーしーしーのばーじょんをかくにんしてから
おまえさんのこーどをくわせてみてるんだよ
せんげんだけしてつかってないへんすうがあるのをけいこくされているけど
それはおまえさんがきにしてるかたのもんだいじゃなさそうだねっていってるの

992 :デフォルトの名無しさん :2020/09/28(月) 10:34:20.53 ID:BXhKM0Xn0.net
>>991
ひらがなでわかりやすくせつめいしてくださったので
あたまのわるいわたしでもようやくわかりました
ありがとうございます

993 :デフォルトの名無しさん :2020/09/28(月) 11:51:02.18 ID:PXJ7xAyjF.net
NULL == 0 // true

ちなみに0は

994 :デフォルトの名無しさん :2020/09/28(月) 11:51:34.94 ID:PXJ7xAyjF.net
NULL == 0 // true

ちなみに0は8進数な

995 :デフォルトの名無しさん :2020/09/28(月) 12:33:12.25 ID:Iit1NWg4M.net
NULL == 0 // true

ちなみに0は8進数なんてことなく10進数なんてことなく16進数なんてこともない

996 :デフォルトの名無しさん :2020/09/28(月) 13:16:35.37 ID:QxfbhGyV0.net
いや8進数だよ
0xで始まったら16進数
0で始まったら8進数

こんな関数作って見たらわかるよ
syukudai("210") == 210
syukudai("110") == 110
syukudai("010") == 8
syukudai("0x10") == 16

997 :デフォルトの名無しさん :2020/09/28(月) 13:27:42.04 ID:zovFJ8Ky0.net
次スレは

998 :デフォルトの名無しさん :2020/09/28(月) 14:23:39.09 ID:qeCUoC3kM.net
みんなの心の中にいつまでもいるさ

999 :デフォルトの名無しさん :2020/09/28(月) 14:46:36.10 ID:MwxSOqxv0.net
質問いいですか?

1000 :デフォルトの名無しさん :2020/09/28(月) 14:57:57.86 ID:Iit1NWg4M.net
>>996
> 0で始まったら8進数

なら、敢えて数字リテラルで8進数のゼロを表すなら 00 だろう。

つか8未満の数「値」に8進数ってなんだYO!!

1001 :2ch.net投稿限界:Over 1000 Thread
2ch.netからのレス数が1000に到達しました。

総レス数 1001
249 KB
掲示板に戻る 全部 前100 次100 最新50
read.cgi ver 2014.07.20.01.SC 2014/07/20 D ★