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

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

1
書き込みが連続して4Kバイトをバッファに残すのはなぜですか?
私は基本的に次のコードを持っています: int fileWrite(int file, void * pBuffer, size_t size) { size_t bytesWritten = (size_t)write( file, pBuffer, size ) ; if (bytesWritten != size) { return -1; } return 0; } サイズが1GBの場合は機能しますが、サイズが〜2GBの場合、一貫して4Kバイトが残ります。書き込みをループでラップしてバッファを上に移動することでこれを修正できますが、なぜそれが常に失敗するのか知りたいです。 たとえば、サイズが2147483648の場合、書き込みは2147479552のみを書き込み、4096は書き込みません。なぜこれが発生し、書き込みを常にループでラップすることが正しいのですか?
30 c  linux  system-calls 

4
CおよびC ++で呼び出される(…)は何ですか?
の用途の1つは、CおよびC ++の可変個のエンティティ...を示すことです。 それの名前は何? そのように使用すると、演算子または何か他のものとして分類されますか? に関するその他の詳細...? 編集: 私はの目的を知ってい...ます。私はその名前と分類について質問しています。これは、CとC ++の両方で類似していると思います。

2
なぜCのBNF文法は、空のinit-declaratorのシーケンスでの宣言を許可するのですか?
CのBNF文法を調べたとき、宣言のプロダクションルールが次のようになっているのは奇妙だと思いました(https://cs.wmich.edu/~gupta/teaching/cs4850/sumII06/The%20syntax%20of%によると) 20C%20in%20Backus-Naur%20form.htm): <declaration> ::= {<declaration-specifier>}+ {<init-declarator>}* ; なぜ*量指定子(0回以上のオカレンス)を使用するのinit-declaratorですか?これにより、int;またはなどのステートメントvoid;は、意味的に無効であっても、構文的に有効になります。プロダクションルールでは+なく、数量詞(1つ以上のオカレンス)を使用しただけではありません*か? 単純なプログラムをコンパイルして、コンパイラーが何を出力するかを確認しましたが、コンパイラーが行うのは警告を出すことだけです。 入力: int main(void) { int; } 出力: test.c: In function ‘main’: test.c:2:5: warning: useless type name in empty declaration int; ^~~

2
2次元配列のエイリアスを作成するときのstrlenの予期しない最適化
これが私のコードです: #include <string.h> #include <stdio.h> typedef char BUF[8]; typedef struct { BUF b[23]; } S; S s; int main() { int n; memcpy(&s, "1234567812345678", 17); n = strlen((char *)&s.b) / sizeof(BUF); printf("%d\n", n); n = strlen((char *)&s) / sizeof(BUF); printf("%d\n", n); } gcc 8.3.0または8.2.1を最適化レベル以外で使用すると-O0、0 2期待していたとおりに出力されます2 2。コンパイラは、strlenがに制限されb[0]ているため、除算される値と同じかそれ以上になることはないと判断しました。 これは私のコードのバグですか、コンパイラのバグですか? これは明確に規格に明記されていませんが、ポインターの来歴の主流の解釈は、どのオブジェクトXでも、コード(char *)&Xは全体を反復できるポインターを生成するべきだと思いましたX-この概念はXたまたま持っていても成り立つはずです内部構造としてのサブ配列。 (ボーナス質問、この特定の最適化をオフにするgccフラグはありますか?)

4
void * function()は関数へのポインターですか、それともvoid *を返す関数ですか?
の意味がわかりませんvoid *function()。 それは関数へのポインタvoid*ですか、それとも関数が戻りますか?私は常にポインタを返す再帰関数としてデータ構造で使用しましたが、マルチスレッド(pthread)でコードを見たとき、同じ関数宣言があります。今、私はそれらの違いが何であるか混乱しています。

3
CにはC ++のstd :: lessと同等のものがありますか?
私は最近やっての未定義の動作に質問に答えるたp < qときCにpし、q異なるオブジェクト/配列へのポインタです。それは私に考えさせました:C ++は<この場合と同じ(未定義)動作を持っていますが、ポインターが比較できる場合std::lessと同じものを返すことが保証され<、できない場合は一貫した順序を返す標準ライブラリテンプレートも提供します。 Cは、(同じ型への)任意のポインタを安全に比較できるようにする同様の機能を持つものを提供していますか?C11標準を調べても何も見つかりませんでしたが、Cでの経験はC ++よりも桁違いに小さいため、簡単に何かを見落としていた可能性があります。

1
Cでのオブジェクトのオーバーラップのセマンティクスは何ですか?
次の構造体について考えてみましょう。 struct s { int a, b; }; 典型的には1、この構造体は、サイズ8と位置合わせ4を有するであろう。 2つのstruct sオブジェクトを作成し(より正確には、2つのオブジェクトを割り当てられたストレージに書き込みます)、2番目のオブジェクトが最初のオブジェクトと重なる場合はどうなりますか? char *storage = malloc(3 * sizeof(struct s)); struct s *o1 = (struct s *)storage; // offset 0 struct s *o2 = (struct s *)(storage + alignof(struct s)); // offset 4 // now, o2 points half way into o1 *o1 …

5
ビット演算は予期しない変数サイズになります
環境 PICマイクロコントローラー用の8ビットCコンパイラーを使用して最初にコンパイルされたCコードを移植しています。符号なしグローバル変数(たとえば、エラーカウンター)がゼロにロールオーバーしないようにするために使用された一般的なイディオムは次のとおりです。 if(~counter) counter++; ここでのビット演算子はすべてのビットを反転し、ステートメントが真であるのcounterは、最大値よりも小さい場合のみです。重要なことに、これは変数のサイズに関係なく機能します。 問題 現在、GCCを使用する32ビットARMプロセッサをターゲットにしています。同じコードが異なる結果を生成することに気づきました。私たちが知る限りでは、ビットごとの補数演算は予想とは異なるサイズの値を返すようです。これを再現するには、GCCでコンパイルします。 uint8_t i = 0; int sz; sz = sizeof(i); printf("Size of variable: %d\n", sz); // Size of variable: 1 sz = sizeof(~i); printf("Size of result: %d\n", sz); // Size of result: 4 出力の最初の行で、期待どおりの結果が得られますi。1バイトです。ただし、のビット単位の補数iは実際には4バイトであり、これとの比較では期待される結果が得られないため、問題が発生します。たとえば、次の場合(i適切に初期化されたはどこですかuint8_t): if(~i) i++; i0xFFから0x00までの「折り返し」が表示されます。この動作は、以前のコンパイラと8ビットPICマイクロコントローラーで意図したとおりに機能していた場合と比較して、GCCで異なります。 次のようにキャストすることでこれを解決できることを認識しています。 if((uint8_t)~i) i++; または、 if(i < 0xFF) …

2
%演算子よりも速い分割可能性テスト?
コンピューターに不思議なことに気づきました。*手書きの分割可能性テストは、%オペレーターよりも大幅に高速です。最小限の例を考えてみましょう: * AMD Ryzen Threadripper 2990WX、GCC 9.2.0 static int divisible_ui_p(unsigned int m, unsigned int a) { if (m <= a) { if (m == a) { return 1; } return 0; } m += a; m >>= __builtin_ctz(m); return divisible_ui_p(m, a); } 例は奇数aとによって制限されm > 0ます。ただし、すべてのaおよびに簡単に一般化できますm。コードは除算を一連の追加に変換するだけです。 でコンパイルされたテストプログラムを考えてみましょう-std=c99 -march=native -O3: for (unsigned …

1
gcc-10.0.1固有のSegfault
私はかなり長い間比較的安定していて、さまざまなプラットフォームとコンパイラ(windows / osx / debian / fedora gcc / clang)に対して頻繁にテストされているCコンパイル済みコードを含むRパッケージを持っています。 最近、パッケージを再度テストするために新しいプラットフォームが追加されました: Logs from checks with gcc trunk aka 10.0.1 compiled from source on Fedora 30. (For some archived packages, 10.0.0.) x86_64 Fedora 30 Linux FFLAGS="-g -O2 -mtune=native -Wall -fallow-argument-mismatch" CFLAGS="-g -O2 -Wall -pedantic -mtune=native -Werror=format-security -Wp,-D_FORTIFY_SOURCE=2 -fexceptions -fstack-protector-strong -fstack-clash-protection -fcf-protection" …

4
Cの絶対値関数がconst入力を受け入れないのはなぜですか?
Cでは、絶対値関数(floatを受け入れる)のプロトタイプは次のとおりです。 float fabsf( float ); このプロトタイプが次のように定数値を受け入れないのはなぜですか。 float fabsf( float const ); fabsfは入力の値を変更しませんか? 入力を受け入れてfabsfを呼び出す関数がある場合、入力をconstとして指定しないように強制されますか? この状況でconstの正確さを処理する適切な方法は何ですか?

9
'\ 0'とCのprintf()
Cの入門コースで、文字列を格納するときに、文字列\0の最後にnull文字が格納されることを学びました。しかし、文字列を印刷したい場合printf("hello")は\0、次のステートメントで終わっていないことがわかりましたが、 printf("%d", printf("hello")); Output: 5 しかし、これは一貫性がないようです。文字列のような変数がメインメモリに格納されることを知っている限り、何かを印刷しているときにメインメモリにも格納される可能性があると思いますが、なぜ違いがあるのでしょうか。
21 c  printf  stdout  c-strings 

2
ラムダマクロはどのようにラムダを作成しますか?
GitHubでこのコードを見つけましたが、よくわかりませんでした。 #define lambda(ret_type, _body) ({ ret_type _ _body _; }) 次に: int (*max)(int, int) = lambda(int, (int x, int y) { return x > y ? x : y; }); int max_value = max(1, 2); // max_value is 2 内部でアンダースコアは何をしていて、#defineどのようにして関数ポインタを返しますか?


3
static int arr [10]メモリアドレスは常に060で終わる
私はこのようなACプログラムを持っています main.c #include <stdio.h> #define SOME_VAR 10 static int heap[SOME_VAR]; int main(void) { printf("%p", heap); return 0; } コンパイルしたプログラムを数回実行すると、これが出力されます 0x58aa7c49060 0x56555644060 0x2f8d1f8e060 0x92f58280060 0x59551c53060 0xd474ed6e060 0x767c4561060 0xf515aeda060 0xbe62367e060 なぜそれが常に060で終わるのですか?そして、配列はヒープに格納されていますか? 編集:私はLinuxを使用していて、ASLRをオンにしています。gccを使用してプログラムをコンパイルしました
17 c  arrays  memory 

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