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

Cは、オペレーティングシステム、ゲーム、その他の高性能作業に使用される汎用のコンピュータープログラミング言語です。

10
「変数を常に初期化する」ことで、重要なバグが隠されることはありませんか?
C ++コアガイドラインには、ES.20:常にオブジェクトを初期化するというルールがあります。 使用前設定エラーとそれに関連する未定義の動作を避けます。複雑な初期化の理解に関する問題を回避します。リファクタリングを簡素化します。 しかし、このルールはバグを見つけるのに役立ちません。バグを隠すだけです。 プログラムに初期化されていない変数を使用する実行パスがあると仮定します。これはバグです。未定義の動作はさておき、それはまた何かがうまくいかなかったことを意味し、プログラムはおそらくその製品要件を満たしていません。本番環境に展開されると、金銭的な損失が発生する可能性があります。 バグをどのように選別しますか?テストを作成します。しかし、テストは実行パスの100%をカバーするわけではなく、テストはプログラム入力の100%をカバーすることはありません。それ以上に、テストでさえ欠陥のある実行パスをカバーします-それはまだパスできます。結局、これは未定義の動作であり、初期化されていない変数はある程度有効な値を持つことができます。 ただし、テストに加えて、0xCDCDCDCDのようなものを初期化されていない変数に書き込むことができるコンパイラーがあります。これにより、テストの検出率がわずかに向上します。 さらに良いことには、初期化されていないメモリバイトのすべての読み取りをキャッチするAddress Sanitizerなどのツールがあります。 最後に、静的アナライザーがあります。これは、プログラムを調べて、その実行パスに事前設定読み取りがあることを伝えることができます。 そのため、多くの強力なツールがありますが、変数を初期化すると、サニタイザーは何も見つかりません。 int bytes_read = 0; my_read(buffer, &bytes_read); // err_t my_read(buffer_t, int*); // bytes_read is not changed on read error. // It's a bug of "my_read", but detection is suppressed by initialization. buffer.shrink(bytes_read); // Uninitialized bytes_read could be detected here. // …
35 c++  c 

8
Clang / LLVMが、列挙されたすべてのケースが含まれるswitchステートメントでデフォルトを使用することについて警告するのはなぜですか?
次のenumおよびswitchステートメントを検討してください。 typedef enum { MaskValueUno, MaskValueDos } testingMask; void myFunction(testingMask theMask) { switch (theMask) { case MaskValueUno: {}// deal with it case MaskValueDos: {}// deal with it default: {} //deal with an unexpected or uninitialized value } }; 私はObjective-Cプログラマですが、より多くの読者のために純粋なCでこれを書いています。 -Weverythingを使用したClang / LLVM 4.1では、デフォルトの行で警告が表示されます。 すべての列挙値をカバーするスイッチのデフォルトラベル 今、私はこれがなぜあるのかを見ることができます:完全な世界では、引数に入力する値theMaskは列挙型のみであるため、デフォルトは必要ありません。しかし、ハックがやって来て、初期化されていないintを美しい関数に投げ込んだらどうなるでしょうか?私の機能はライブラリのドロップとして提供され、そこに何が入るかを制御することはできません。を使用することdefaultは、これを処理する非常に適切な方法です。 なぜLLVMの神は、この振る舞いを地獄のデバイスにふさわしくないと考えているのでしょうか?引数をチェックするifステートメントをこれに先行させる必要がありますか?

5
自分の言語を最初にCコードにコンパイルするのが理にかなっているのはいつですか?
独自のプログラミング言語を設計するとき、gccなどの既存のコンパイラを使用してマシンコードを作成できるように、ソースコードを取得してCまたはC ++コードに変換するコンバーターを記述するのはいつ意味がありますか?このアプローチを使用するプロジェクトはありますか?

8
Javaがif(5){…} if Cのような数値条件を厳密に許可しないのはなぜですか?
次の2つの小さなプログラムがあります。 C #include <stdio.h> int main() { if (5) { printf("true\n"); } else { printf("false\n"); } return 0; } Java class type_system { public static void main(String args[]) { if (5) { System.out.println("true"); } else { System.out.println("false"); } } } エラーメッセージを報告します。 type_system.java:4: error: incompatible types: int cannot be converted to …
33 java  c  type-systems 

5
パラメーターを介して、または戻り値によってC構造体を初期化する必要がありますか?[閉まっている]
私が働いている会社は、次のような初期化関数を使用して、すべてのデータ構造を初期化しています。 //the structure typedef struct{ int a,b,c; } Foo; //the initialize function InitializeFoo(Foo* const foo){ foo->a = x; //derived here based on other data foo->b = y; //derived here based on other data foo->c = z; //derived here based on other data } //initializing the structure Foo foo; InitializeFoo(&foo); 私はこのような構造体を初期化しようとするいくつかのプッシュバックを得ました: …

7
パフォーマンスのためにCで作成しますか?[閉まっている]
Cは通常C ++よりもパフォーマンスが優れているとよく耳にします。MSVCがCの最新の標準をサポートしていないように思えるまで、それ以外のことは何も考えていませんでしたが、最新のものはC99をサポートしています(私の知る限り)。 OpenGLでレンダリングするためのコードを含むライブラリを作成して、再利用できるようにすることを計画していました。グラフィックに関しては、パフォーマンスの向上を歓迎するため、ライブラリをCで作成することを計画していました。 しかし、それは本当に価値があるでしょうか?ライブラリを使用するコードはおそらくC ++で書かれているため、一般的にはC ++でコーディングすることを好みます。 ただし、パフォーマンスにわずかな違いさえ生じる場合は、Cを使用します。 また、このライブラリは、Windows / OS X / Linux全体で動作するようにするものであり、すべてをネイティブにコンパイルする可能性があります(Windows用のMSVC、OS X用のClangまたはGCC、およびLinux用のGCC)。 。またはおそらくすべてのインテルのコンパイラ)。 私は周りを見回し、いくつかのベンチマークなどを見つけましたが、私が見たものはすべて、MSVCとClangではなくGCCを扱っています。また、ベンチマークでは使用言語の標準については言及していません。誰もこれについて考えていますか? 編集:数年以上の経験を経て、この質問に対する私の見解を共有したかっただけです。C ++でこの質問をしていたプロジェクトを書くことになりました。私は、Cでリンクできるようにするために、できる限り少量のパフォーマンスを引き出したいと考えていたのと同じ頃に、Cで別のプロジェクトを開始しました。数ヶ月前、私は本当にマップと高度な文字列操作。私はC ++標準ライブラリのこの能力を知っていて、最終的に標準ライブラリのそれらの構造は、妥当な時間内にCで実装できるマップや文字列よりもパフォーマンスが高く安定しているという結論に達しました。Cでリンク可能であるという要件は、C ++コードへのCインターフェイスを記述することで簡単に満たされました。これは、不透明(OPAQUE)型で迅速に行われました。C ++でのライブラリの書き換えは、Cでの書き込みよりもはるかに高速であるようで、バグ、特にメモリリークが発生しにくい傾向がありました。プラットフォーム固有の実装を使用するよりもはるかに簡単な標準ライブラリスレッドライブラリを使用することもできました。最終的には、C ++でライブラリを作成することで、パフォーマンスコストをわずかに抑えながら大きなメリットを得ることができたと思います。私はまだC ++バージョンのベンチマークを行っていませんが、私が書いたものよりも標準ライブラリのデータ構造を使用することで、ある程度のパフォーマンスを得た可能性さえあると信じています。ライブラリをC ++で記述すると、パフォーマンスコストはおそらくわずかですが、大きなメリットが得られたと思います。私はまだC ++バージョンのベンチマークを行っていませんが、私が書いたものよりも標準ライブラリのデータ構造を使用することで、ある程度のパフォーマンスを得た可能性さえあると信じています。ライブラリをC ++で記述すると、パフォーマンスコストはおそらくわずかですが、大きなメリットが得られたと思います。私はまだC ++バージョンのベンチマークを行っていませんが、私が書いたものよりも標準ライブラリのデータ構造を使用することで、ある程度のパフォーマンスを得た可能性さえあると信じています。

11
typedefsおよび#defines
私たちは皆、間違いなくtypedefsと#definesを使用しました。今日、彼らと仕事をしている間、私は物事について熟考し始めました。 int別の名前のデータ型を使用するには、以下の2つの状況を考慮してください。 typedef int MYINTEGER そして #define MYINTEGER int 上記の状況のように、多くの状況で、#defineを使用して非常にうまく処理でき、typedefを使用して同じことを実行できますが、同じことを行う方法はまったく異なる場合があります。#defineは、typedefではできないMACROアクションも実行できます。 それらを使用する基本的な理由は異なりますが、動作はどの程度異なりますか?両方を使用できる場合に、一方が他方よりも優先される場合 また、一方の状況では、他方よりも高速であることが保証されていますか?(たとえば、#defineはプリプロセッサディレクティブであるため、すべてがコンパイルまたは実行時よりも早く実行されます)。

13
低レベルのプログラミング-私にとってそれは何ですか?[閉まっている]
何年もの間、「低レベル」言語と考えるものを掘り下げることを考えてきました。私にとって、これはCとアセンブリを意味します。しかし、私はまだこれをする時間がありませんでしたし、これまで必要だったこともありません。 必要性が生じていないので、主題を勉強する予定のある時点をスケジュールするか、永遠に計画を破棄する必要があると感じています。 私の位置 過去4年間、私は変化する可能性のある「Webテクノロジー」に注力してきました。また、私はアプリケーション開発者であり、変化することはほとんどありません。 アプリケーション開発では、ユーザビリティが最も重要だと思います。ユーザーが「消費」するアプリケーションを作成します。これらのアプリケーションが使いやすくなればなるほど、より多くの価値を生み出します。 使い勝手を良くするために、次のことが実行可能であると信じています 優れた設計:よく考え抜かれたユーザーインターフェイスからアクセスできる、よく考えられた機能。 正しさ:正しく実装されていなければ、最高のデザインは価値がありません。 柔軟性:アプリケーションAは絶えず進化する必要があるため、ユーザーは、Aが実装できる新しい機能を備えた別のアプリケーションBに切り替える必要はありません。同じ問題に対処するアプリケーションは、機能ではなく哲学が異なるはずです。 パフォーマンス:パフォーマンスは、優れたユーザーエクスペリエンスに貢献します。アプリケーションは理想的には常に応答性が高く、(頻度に基づいて)合理的に高速にタスクを実行します。ユーザーが認識できる以上のパフォーマンス最適化の価値は疑問です。 パフォーマンスを除いて、低レベルのプログラミングはそれを助けてくれないと思います。しかし、パフォーマンスのために低レベル言語でアプリ全体を書くことは、私にとって時期尚早な最適化です。 私の質問 低レベルのプログラミングは何を教えてくれますか?他の言語は教えてくれませんか?アプリケーション開発にほとんど役に立たない何かが足りないのですか、それとも単なるスキルですか?私がCとアセンブリの価値に疑問を抱いていないことを理解してください。私の日常生活の中で、私はその世界の複雑さをすべて取り除いて、私のために管理していることを非常に嬉しく思っています(ほとんどがC / C ++で記述されたレイヤーとアセンブリ自体によって)。概念がまったく見当たらず、それは私にとっては新しいことかもしれませんが、頭に詰め込む必要のある詳細だけです。それで私にとっては何ですか? 私の結論 回答ありがとうございます。誰も私を驚かせた人はいませんが、少なくとも今は、この必要な領域が必要になるまでこの領域を削除することを確信しています。 私の理解では、最近のプロセッサーが今日のCPUで使用されているときにアセンブリーを記述することは、不必要に複雑であるだけでなく、Cのカウンターパートよりも実行時のパフォーマンスが低下するリスクがあります。手作業による最適化はOOEによりほぼ不可能ですが、コンパイラーが自動的に実行できるすべての種類の最適化は得られません。また、使用可能なコマンドの小さなサブセットを使用するため、または最適化されているため、コードは移植可能ですが、おそらく1つのアーキテクチャでのみ動作します。 Cを書くことは、以前ほど必要ではなくなった。Cでアプリケーションを作成する場合、テストおよび確立されたライブラリとフレームワークを同様に使用します。これにより、文字列コピールーチン、ソートアルゴリズム、および大学での演習として役立つその他の種類の実装が不要になります。私自身のコードは、タイプセーフを犠牲にして高速に実行されます。私は通常のアプリ開発の過程で車輪を再発明することにも、コアダンプを見てデバッグしようとすることにも熱心ではありません:D 私は現在言語とインタプリタで実験しているので、何か公開したいことがあるなら、私は思うC ++がうまく機能するかもしれませんが、実用的な概念をCに移植します。 繰り返しますが、皆さんの回答と洞察に感謝します。

8
Makeを直接使用することは時代遅れと見なされますか?[閉まっている]
ですから、メイクファイルを直接作成することや、2015年にそれを行うのは馬鹿げたことです。CMakeなどのツールを知っており、実際にCMakeを頻繁に使用しています。大切なのは、CMakeはMakefileを作成して、自分でそれを行うという退屈な作業をなくすことです。もちろん、それは他の多くの素晴らしい機能を追加します...しかし、最終的にはまだMakefileです。 だから私の質問は、Makeユーティリティ全体を指すmakeに関する「時代遅れの」話ですか、それとも自分のMakefileを手動で書くというアイデアですか?私はC / C ++開発にIDEをまったく使用しません(ちょうどemacs)ので、常にMakefileを作成しました。 Makeが古いと見なされる場合、C / C ++開発者は小さな個人プロジェクトを構築するために何を使用すべきですか?
31 c++  c  builds  make  cmake 

2
Cプリプロセッサの起源は何ですか?
CプリプロセッサはCに接続されていますが、メイン言語とはまったく異なる構文を持っています。 構文的に重要な空白(行の終わりはステートメントを終了し、マクロが置換リストの開始を決定した後のギャップ) キーワードベースの代わりにブレースブロックのブロック、elif代わりにelse if 宣言-反映-使用の代わりにキーワード主導の定義=、値の定義は不可 代替文字列構文のヒント(#include <>vs #include "") 怠evaluationな評価(Cのことは明らかですが、6.10.3.1は、重要ないくつかの場所で、マクロ展開の特定の順序を暗示していると読むこともできます) まったくCのようには見えません!技術的には独自の言語ですが、常にCのほぼ統合された部分として使用されており、構文的に統合されないことは非常に奇妙に思えます。 ウィキペディアはその歴史について語っていません。Portland Pattern Repository にはパスの言及がありますが、Cの歴史を持つ他の人々によって設計されたという事実を超えて詳細に説明することはありません。より長く利用可能。 マクロエンジンとして、それは明らかに説明するだろうランタイム言語から非常に異なる意味があるいくつかの違いがではなく、視覚的なデザインの側面を(それがもともとあるものとして意図されていたかどうかも現代の目には不明だが可能なの種類の楽しみのこと置換システムでは、強力なオプティマイザーが登場する前に関数をインライン化するための「単なる」適切な方法であったか、またはそうであったかを確認できます。Cのようなセマンティクスが実際に出発点だった場合、最終的にC ++テンプレートになったものに近いものがマクロに向かってより論理的な進化を遂げたように感じますが、構文に関するよりも具体的な証拠はありません。 なぜこのように設計されたのか、クリエイターの影響がどのようなものだったのかについての記録はありますか?
30 c  history  macros 

5
数値が大きすぎる場合、次のメモリ位置にあふれますか?
私はCプログラミングをレビューしてきましたが、気になっていることがいくつかあります。 例としてこのコードを見てみましょう: int myArray[5] = {1, 2, 2147483648, 4, 5}; int* ptr = myArray; int i; for(i=0; i<5; i++, ptr++) printf("\n Element %d holds %d at address %p", i, myArray[i], ptr); intは正の2,147,483,647の最大値を保持できることを知っています。それで、それを越えて、次のメモリアドレスに「あふれ」、そのアドレスで要素2が「-2147483648」として表示されるのでしょうか。しかし、出力では次のアドレスが値4、5を保持していることを示しているため、それは実際には意味がありません。数値が次のアドレスにあふれた場合、そのアドレスに格納されている値は変更されません? MIPS Assemblyでのプログラミングと、プログラム中にアドレスが値を変更するのを見て、それらのアドレスに割り当てられた値が変わることを漠然と覚えています。 間違って覚えていない限り、別の質問があります:特定のアドレスに割り当てられた番号がタイプ(myArray [2]のように)よりも大きい場合、後続のアドレスに格納されている値には影響しませんか? 例:int myNum = 40億がアドレス0x10010000にあります。もちろん、myNumは40億を保存できないため、そのアドレスでは負の数として表示されます。この大きな数を格納することはできませんが、後続のアドレス0x10010004に格納されている値には影響しません。正しい? メモリアドレスには、特定のサイズの数字/文字を保持するのに十分なスペースがあり、サイズが制限を超えた場合、異なるように表示されます(intに40億を格納しようとしているが、負の数として表示されます)そのため、次のアドレスに保存されている数字/文字には影響しません。 船外に行ったら申し訳ありません。私はこれから一日中大きな脳のおならをしていました。

10
ポインターがC言語で保持するデータの「タイプ」とは何ですか?
ポインタがアドレスを保持していることを知っています。ポインターのタイプは、ポインターが指すデータの「タイプ」に基づいて「一般に」知られていることを知っています。ただし、ポインターは依然として変数であり、ポインターが保持するアドレスにはデータ「タイプ」が必要です。私の情報によると、アドレスは16進形式です。しかし、この16進数のデータの「タイプ」はまだわかりません。(16進数が何であるかはわかっていますが、10CBA20たとえば、この文字列は整数ですか?整数ですか?アドレスにアクセスしてそれ自体を操作したい場合は、そのタイプを知る必要があります。私が尋ねている理由です。)
30 c  pointers 


2
C文字列リテラルが読み取り専用なのはなぜですか?
文字列リテラルが読み取り専用であることの利点は、以下を正当化(-ies / -ied)します: 足で自分を撃つ別の方法 char *foo = "bar"; foo[0] = 'd'; /* SEGFAULT */ 1行で単語の読み書き配列をエレガントに初期化できない: char *foo[] = { "bar", "baz", "running out of traditional placeholder names" }; foo[1][2] = 'n'; /* SEGFAULT */ 言語自体を複雑にします。 char *foo = "bar"; char var[] = "baz"; some_func(foo); /* VERY DANGEROUS! */ some_func(var); /* …
29 c  memory  strings 

10
ポインター変数の使用はメモリのオーバーヘッドではありませんか?
CやC ++などの言語では、変数へのポインターを使用しているときに、そのアドレスを格納するためにもう1つのメモリの場所が必要です。これはメモリのオーバーヘッドではありませんか?これはどのように補償されますか?ポインターは、タイムクリティカルな低メモリアプリケーションで使用されていますか?
29 c++  c  pointers 

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