タグ付けされた質問 「c」

Cは、システムプログラミング(OSおよび組み込み)、ライブラリ、ゲーム、クロスプラットフォームに使用される汎用プログラミング言語です。このタグは、ISO 9899標準で定義されているC言語に関する一般的な質問で使用する必要があります(特に指定のない限り、最新バージョン9899:2018。バージョン固有のリクエストには、c89、c99、c11などのタグも付けます)。CはC ++とは異なり、合理的な理由がない限り、C ++タグと組み合わせるべきではありません。

1
異なるコンパイラーでのvoid **への変換
次のコードをさまざまなコンパイラで実行しています。 int main() { float **a; void **b; b = a; } 私が収集できたことから、汎用ポインタでvoid **はありません。これは、別のポインタからの変換がコンパイルされたり、少なくとも警告をスローしたりしないことを意味します。しかし、ここに私の結果があります(すべてWindowsで行われます): gcc-期待どおりに警告をスローします。 g ++ -予想どおりエラーをスローします(これは、C ++の型の許容度が低いためです)。 MSVC(cl.exe) -/ Wallが指定されていても、警告は一切表示されません。 私の質問は、全体について何か不足しているのですか?MSVCが警告を生成しない特定の理由はありますか?MSVC は、から void **への変換時に警告を生成しfloat **ます。 もう1つの注意点:a = b明示的な変換に置き換えた場合a = (void **)b、どのコンパイラも警告をスローしません。これは無効なキャストだと思ったので、なぜ警告がないのでしょうか? 私がこの質問をしているのは、CUDAと公式のプログラミングガイド(https://docs.nvidia.com/cuda/cuda-c-programming-guide/index.html#device-memory)を学び始めていたからです。次のコードが見つかります: // Allocate vectors in device memory float* d_A; cudaMalloc(&d_A, size); の最初の引数は型であるvoid **ため&d_A、これはfor への暗黙の変換を実行する必要cudaMallocがありvoid **ます。同様のコードがドキュメント全体にあります。これはNVIDIAの終わりのずさんな作業ですか、それとも私は何か不足していますか?nvccはMSVCを使用しているため、コードは警告なしでコンパイルされます。
9 c++  c  cuda 

1
Linuxでプロセスが新しいファイル記述子を開かないようにするが、ソケット経由でファイル記述子を受信できるようにする
私は現在、ソケットペアをセットアップしてフォークし、このソケットペアを使用して通信する親プロセスがあるプロジェクトに取り組んでいます。子は、ファイル(またはその他のファイル記述子ベースのリソース)を開きたい場合は常に親に移動し、リソースを要求しfdて、socketpair経由で送信されます。さらに、子供が自分でファイル記述子を開かないようにしたいと思います。 私はつまずきましsetrlimitたが、子が新しいファイル記述子を開くことができなくなりましたが、最初のソケット接続で送信されたファイル記述子が無効になるようです。単一のプロセスが任意のファイルを開き、そのファイル記述子を他のプロセスに送信し、これらの他のプロセスが自分でファイル記述子を開くことを許可せずにそれらを使用できるようにするLinuxのメソッドはありますか? 私のユースケースでは、フォーク後に適用でき、すべてのファイル記述子(ファイルだけでなく、ソケット、ソケットペアなど)にも適用できる限り、カーネル構成、システムコールなどを使用できます。
9 c  linux  system-calls 

1
不完全な型へのポインタは不完全なのでしょうか?
することができint (*)[]、不完全型で? C 2018 6.2.5 1は言う: 翻訳単位内のさまざまな時点で、オブジェクトタイプは不完全(そのタイプのオブジェクトのサイズを決定するのに十分な情報がない)または完全(十分な情報がある)の場合があります。 したがって、型のサイズがわかっていれば、型は完全であるように見えます。6.2.6.1 28は、特定のタイプのポインターは同じサイズ(ポインターvoidと文字、互換タイプへのポインター、構造体へのポインター、および共用体へのポインター)でなければならないことを指定していますが、他のタイプへのポインターは異なる場合があります。 すべてのポインター、またはの配列へのすべてのポインターがint同じサイズであるCの実装では、のサイズint (*)[]がわかっているため、完全なサイズになります。たとえば、大きな配列に異なるポインタを使用する実装では、サイズがわからないため、不完全です。 以下のようにMMが指摘し、構造これは、ポインタのサイズの実装が受け入れなければならないことを示唆している6.7.2.1 3に制約ごとに、最終的な可撓性のアレイメンバーを除き、不完全な型とメンバーを含んではならないstruct { int (*p)[]; }異なる有する実装ながらそのような配列のサイズは、制約違反を診断する必要があります。(これは、そのような宣言が厳密に準拠するCの一部ではないことを意味します。)

3
なぜLLVMは冗長変数を割り当てるのですか?
列挙型の定義とmain関数を含む簡単なCファイルを次に示します。 enum days {MON, TUE, WED, THU}; int main() { enum days d; d = WED; return 0; } 次のLLVM IRに転送されます。 define dso_local i32 @main() #0 { %1 = alloca i32, align 4 %2 = alloca i32, align 4 store i32 0, i32* %1, align 4 store i32 2, i32* …
9 c  llvm  llvm-codegen 

1
CHAR_WIDTHが宣言されていません
‘CHAR_WIDTH’ undeclared この単純なプログラムをコンパイルしようとすると、エラーが発生 します。 #include <stdio.h> #include <limits.h> int main() { printf("CHAR_BIT = %d\n", CHAR_BIT); printf("CHAR_WIDTH = %d\n", CHAR_WIDTH); return (0); } と gcc ./show_char_width.c -o show_char_width およびgcc:GNU C17(Ubuntu 8.3.0-6ubuntu1)バージョン8.3.0(x86_64-linux-gnu)、GNU Cバージョン8.3.0、GMPバージョン6.1.2、MPFRバージョン4.0.2、MPCバージョン1.1.0でコンパイル、islバージョンisl-0.20-GMP、カーネル:5.0.0-37-generic。 ここで述べたように、 CHAR_WIDTHはプログラムに含まれているlimits.hで定義する必要があります。では、なぜこのエラーが発生するのですか? では-vオプション私は、ライブラリは、これらのディレクトリで検索されますことを見出しました。 #include "..." search starts here: #include <...> search starts here: /usr/lib/gcc/x86_64-linux-gnu/8/include /usr/local/include /usr/lib/gcc/x86_64-linux-gnu/8/include-fixed /usr/include/x86_64-linux-gnu /usr/include / …
9 c  gcc 

1
非常に単純なコードからの「違法なハードウェア命令」
疑わしい主張を調査しながら、私はこの小さなテストプログラムを書きましたnoway.c int proveit() { unsigned int n = 0; while (1) n++; return 0; } int main() { proveit(); return 0; } これをテストすると、私は得ます: $ clang -O noway.c $ ./a.out zsh: illegal hardware instruction ./a.out ワット。 最適化せずにコンパイルすると、期待どおりにハングします。私はアセンブリを見て、すべてのベルとホイッスルがないと、main関数は次のようになります。 _main: ## @main pushq %rbp movq %rsp, %rbp ud2 どこud2が明らかに未定義の動作専用の命令です。前述の「決して戻ることのない機能はUBです」という疑わしい主張が強化されています。まだ信じられないけど。本当に!?あなたは安全にスピンループを書くことができないのですか? だから私は私の質問だと思います: これは何が起こっているのか正しい読みですか? もしそうなら、誰かがそれを検証する公式のリソースを私に示すことができますか? このタイプの最適化を実行したい状況は何ですか? …

1
mandelbrot brainf ***プログラムの実行中にプログラムが動かなくなるのはなぜですか?
Cのスキルを磨きたかったので、プログラムのアイデアを探しました。 誰かが単純なBrainf ***インタープリターを作成してからコンパイラーを作成することを提案します。だからここにいます。 私はインタプリタを作成しましたが、マンデルブロプログラムを除いて、期待どおりに動作します。 A mandelbrot set fractal viewer in brainfuck written by Erik Bosman +++++++++++++[->++>>>+++++>++>+<<<<<<]>>>>>++++++>--->>>>>>>>>>+++++++++++++++[[ >>>>>>>>>]+[<<<<<<<<<]>>>>>>>>>-]+[>>>>>>>>[-]>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>[-]+ <<<<<<<+++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>>>+>>>>>>>>>>>>>>>>>>>>>>>>>> >+<<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+[>>>>>>[>>>>>>>[-]>>]<<<<<<<<<[<<<<<<<<<]>> >>>>>[-]+<<<<<<++++[-[->>>>>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>>+<<<<<<+++++++[-[->>> >>>>>>+<<<<<<<<<]>>>>>>>>>]>>>>>>+<<<<<<<<<<<<<<<<[<<<<<<<<<]>>>[[-]>>>>>>[>>>>> >>[-<<<<<<+>>>>>>]<<<<<<[->>>>>>+<<+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>> [>>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<+<<]>>>>>>>>]<<<<<<<<<[<<<<<<< <<]>>>>>>>[-<<<<<<<+>>>>>>>]<<<<<<<[->>>>>>>+<<+<<<<<]>>>>>>>>>+++++++++++++++[[ >>>>>>>>>]+>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[ >+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>[-<<<<+>>>>]<<<<[->>>>+<<<<<[->>[ -<<+>>]<<[->>+>>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<< <<[>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<< [>[-]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<<<]<+<<<<<<<<<]>>>>> >>>>[>+>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+ <<<<<<[->>>[-<<<+>>>]<<<[->>>+>+<<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>> >>>>>>>]<<<<<<<<<[>>[->>>>>>>>>+<<<<<<<<<]<<<<<<<<<<<]>>[->>>>>>>>>+<<<<<<<<<]<< +>>>>>>>>]<<<<<<<<<[>[-]<->>>>[-<<<<+>[<->-<<<<<<+>>>>>>]<[->+<]>>>>]<<<[->>>+<< <]<+<<<<<<<<<]>>>>>>>>>[>>>>[-<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<+>>>>>>>>>>>>> >>>>>>>>>>>>>>>>>>>>>>>]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>> >>>>>]<<<<<<<<<-<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+>>>>>>>>>>>>>>>>>>>>>+<<<[<<<<<< <<<]>>>>>>>>>[>>>[-<<<->>>]+<<<[->>>->[-<<<<+>>>>]<<<<[->>>>+<<<<<<<<<<<<<[<<<<< <<<<]>>>>[-]+>>>>>[>>>>>>>>>]>+<]]+>>>>[-<<<<->>>>]+<<<<[->>>>-<[-<<<+>>>]<<<[-> >>+<<<<<<<<<<<<[<<<<<<<<<]>>>[-]+>>>>>>[>>>>>>>>>]>[-]+<]]+>[-<[>>>>>>>>>]<<<<<< <<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]<<<<<<<[->+>>>-<<<<]>>>>>>>>>+++++++++++++++++++ +++++++>>[-<<<<+>>>>]<<<<[->>>>+<<[-]<<]>>[<<<<<<<+<[-<+>>>>+<<[-]]>[-<<[->+>>>- <<<<]>>>]>>>>>>>>>>>>>[>>[-]>[-]>[-]>>>>>]<<<<<<<<<[<<<<<<<<<]>>>[-]>>>>>>[>>>>> [-<<<<+>>>>]<<<<[->>>>+<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>>[-<<<<<<<< <+>>>>>>>>>]>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>+++++++++++++++[[>>>>>>>>>]+>[- ]>[-]>[-]>[-]>[-]>[-]>[-]>[-]>[-]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>-]+[>+>>>>>>>>]<<< <<<<<<[<<<<<<<<<]>>>>>>>>>[>->>>>>[-<<<<<+>>>>>]<<<<<[->>>>>+<<<<<<[->>[-<<+>>]< <[->>+>+<<<]+>>>>>>>>>]<<<<<<<<[<<<<<<<<<]]>>>>>>>>>[>>>>>>>>>]<<<<<<<<<[>[->>>> >>>>>+<<<<<<<<<]<<<<<<<<<<]>[->>>>>>>>>+<<<<<<<<<]<+>>>>>>>>]<<<<<<<<<[>[-]<->>> [-<<<+>[<->-<<<<<<<+>>>>>>>]<[->+<]>>>]<<[->>+<<]<+<<<<<<<<<]>>>>>>>>>[>>>>>>[-< <<<<+>>>>>]<<<<<[->>>>>+<<<<+<]>>>>>>>>]<<<<<<<<<[<<<<<<<<<]>>>>>>>>>[>+>>>>>>>> …

2
Cでのコンパイル時のカプセル化とは何ですか?
C ++に対するCの利点を調査していたとき、この段落に出くわしました。 Cでカプセル化を行う標準的な方法は、構造体を転送宣言し、関数を介してそのデータへのアクセスのみを許可することです。このメソッドは、コンパイル時のカプセル化も作成します。コンパイル時のカプセル化により、クライアントコード(インターフェイスを使用する他のコード)を再コンパイルすることなく、データ構造のメンバーを変更できます。一方、(クラスを使用して)カプセル化C ++を行う標準的な方法では、プライベートメンバー変数を追加または削除するときにクライアントコードを再コンパイルする必要があります。 構造体を宣言し、関数を介してそのメンバーにアクセスすることで、構造体の実装の詳細がどのように隠されるかを理解しています。私が理解していないのは、特にこの行です: コンパイル時のカプセル化により、クライアントコード(インターフェイスを使用する他のコード)を再コンパイルすることなく、データ構造のメンバーを変更できます。 これはどのシナリオに当てはまりますか?
9 c 

6
ビットごとのAND演算子を使用した配列宣言へのCポインター
次のコードを理解したいと思います。 //... #define _C 0x20 extern const char *_ctype_; //... __only_inline int iscntrl(int _c) { return (_c == -1 ? 0 : ((_ctype_ + 1)[(unsigned char)_c] & _C)); } これは、obenbsdオペレーティングシステムのソースコードのctype.hファイルに由来します。この関数は、charがASCII文字の範囲内の制御文字または印刷可能な文字であるかどうかをチェックします。これが私の現在の考えの連鎖です: iscntrl( 'a')が呼び出され、 'a'がその整数値に変換されます 最初に_cが-1かどうかを確認し、次に0を返します... 未定義のポインタが指すアドレスを1だけインクリメントします このアドレスを長さの配列へのポインタとして宣言する(unsigned char)((int) 'a') ビットごとのand演算子を_C(0x20)と配列(???)に適用します。 どういうわけか、奇妙なことに、それは機能し、0が返されるたびに、指定されたchar _cは印刷可能な文字ではありません。それ以外の場合、それが印刷可能である場合、関数は特別な関心のない整数値を返すだけです。私の理解の問題は、ステップ3、4(少し)および5にあります。 助けてくれてありがとう
9 c  openbsd 

3
foo(void)とfoo(void *)
機能的および構文的に言えば、プロトタイプの関数とには違いがint foo(void)ありint foo(void *)ますか? 私は、例えば、違いを知って、int bar(int)そしてint bar(int *)-そのうちの一つがintを探している、と他のはint型のポインタを探しています。void同じように動作?

3
+(+ k--)Cの式
この質問は、次のコードの出力を通知する必要があるテストで見ました。 #include<stdio.h> int main(){ int k = 0; while(+(+k--)!=0) k=k++; printf("%d\n", k); return 0; } 出力は-1です。なぜこれが答えなのかはわかりません。 +(+k--)Cでの表現の意味は?
9 c 

4
sizeofは、配列へのポインターのこの逆参照でどのように機能しますか?
ここに私は4つの整数のptr配列へのポインターがarrあります。ptr配列全体を指します。ptr[0]または*ptr配列の最初の要素を指すため、1を追加して配列ptr[0]の2番目の要素のアドレスを取得します。 sizeof(ptr[0])(ptr[0]配列の最初の要素へのポイントとして)最初の要素のみのサイズである4バイトではなく、配列全体のサイズが16バイトになる理由を理解できません。 int arr[4] = {0, 1, 2, 3}; int (*ptr)[4] = &arr; printf("%zd", sizeof(ptr[0])); //output is 16
9 c  arrays  pointers 

1
Javaのオブジェクト初期化“ Foo f = new Foo()”は、Cのポインターにmallocを使用することと本質的に同じですか?
Javaでのオブジェクト作成の背後にある実際のプロセスを理解しようとしています。他のプログラミング言語もあると思います。 Javaでのオブジェクトの初期化がCで構造体にmallocを使用する場合と同じであると想定するのは間違っているでしょうか? 例: Foo f = new Foo(10); typedef struct foo Foo; Foo *f = malloc(sizeof(Foo)); これが、オブジェクトがスタックではなくヒープ上にあると言われるのはなぜですか?それらは本質的にデータへの単なるポインタなので?

4
Cコンパイラがスイッチを最適化する理由と異なる場合
最近、奇妙な問題に遭遇したとき、私は個人的なプロジェクトに取り組んでいました。 非常にタイトなループでは、0〜15の値の整数があります。値0、1、8、9の場合は-1を取得し、値4、5、12、13の場合は1を取得する必要があります。 私はいくつかのオプションを確認するためにgodboltを使用しましたが、コンパイラーがifチェーンと同じ方法でswitchステートメントを最適化できないようであることに驚きました。 リンクはここにあります:https://godbolt.org/z/WYVBFl コードは次のとおりです。 const int lookup[16] = {-1, -1, 0, 0, 1, 1, 0, 0, -1, -1, 0, 0, 1, 1, 0, 0}; int a(int num) { return lookup[num & 0xF]; } int b(int num) { num &= 0xF; if (num == 0 || num == 1 || …


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.