文字列リテラルの長さを知るコンパイル時の最適化を使用して、文字列を書き込むためのマクロを作成します。しかし、ポインタを使って誤用を検出する必要があります。Cマクロで定数文字列をchar *と区別する方法
は、ここで私が何を意味するかです:2回目の呼び出しで
void transmit(const char *data, int length);
#define tx_string(x) transmit((x), sizeof(x) -1)
void func(char *badmsg) {
tx_string("GO"); // ok
tx_string(badmsg); // not OK
}
を、サイズが(ポインタのsizeof)ナンセンスになります。
文字列リテラル以外にtx_stringを使用しようとすると、コンパイル時エラーが発生します。これはgccを使用しています。私はこれを行うために使用できるいくつかのgccのことはありますか?
編集:私はNULLを含む可能性がありますか、NULLで終わらないデータバッファを扱います。私は本当にこのためにポインタが使用されないようにし、実行時間を防ぐためにstrlen()
を使用します。
編集2:
問題の原因となる例を示します。 私は、16ビットのマイクロコントローラに16ビットのraw(2つの8ビット文字)としてアドレスが続くGOコマンドを使って16ビットのマイクロコントローラにアドレスを伝え、アドレス0から行きたいという想像上のプロトコルを発明します。
#define GOSEQ "GO\000\000"
void func(void) {
char *bad = GOSEQ;
tx_string(GOSEQ); // ok, sends 4 bytes: GO and two zero bytes
tx_string(bad); // bad, using runtime strlen sends two characters "GO"
}
これについてgcc組み込みチェックが必要であると確信しています。私は、このようなコンパイル時の区別の仕掛けを使ってLinuxカーネルのソースを見ていますが、特定のものに手を置くことはできません。
これまでのところ、「Windowsプログラマー」の考えはよく見えますが、より意味のあるコンパイル時のエラーがボーナスになります。あなたがこれを行うことができます
これは勝者のようです!私はちょうど誰かが完璧な組み込みテストや何かを考え出す場合にちょっと待っています。 – blueshift