2

I am working with doing some serial communications in C in Linux. I am doing this using file descriptors. For some reason after char* s = "Hello world", I can write s to the serial port using the write method, no problem. I am using a serial monitor program to check the other end. However, I cannot send any other sort of data. I get a "Bad Address" error from the write function.

However, I noticed that if I did something very strange: int* x = "5"; That I could then send this x. My question is, what in the world does int* x = "5" mean?

4

3 に答える 3

3
int* x = "5"; 

これは有効なCコードではありません。配列の値をにキャストする必要がありint *ますが、ポインターの逆参照は、アライメントルールに違反し、未定義の動作になる可能性があります。

int *x =  (int *) "5";

この最後のコードは、タイプが。の名前のない配列オブジェクトを格納しますchar [2]。の値は"5"最初の要素へのポインタであり、ポインタはchar *。です。キャストはをに変換char *し、 int *に格納しxます。

于 2012-04-28T19:46:31.963 に答える
2
int* x = "5";

制約違反です。つまり、準拠するコンパイラは、その診断を発行する必要があります。これを致命的なエラーとして扱う必要はありません。コンパイラは、警告を発行してからプログラムを正常に変換できます。しかし、言語はこの宣言の振る舞いを定義しません。

(崩壊後char*の の型)から への暗黙的な変換はありません。"5"int*

これは、C が何かが違法であると言っているのと同じくらい近いものです。

実際には、この宣言を受け入れるコンパイラは、おそらく次のものと同等に扱います。

int *x = (int*)"5";

つまり、変換を挿入します。(これが唯一の可能な解釈ではありませんが、ほとんどのコンパイラは、このように解釈するか、拒否します。) これはchar*、配列式の減衰から生じる値(つまり、配列の先頭にある文字"5"のアドレス) を取ります。'5'文字列)、に変換されint*ます。

結果のポインターは、有効である場合と有効でない場合がint*あるオブジェクトを指します。int文字列の"5"長さは 2 バイトです ( { '5', '\0' })。int2 バイトの場合*x、これらの 2 バイトを値として解釈した結果として評価される場合がありintます。これは、システムのエンディアンに依存します。または、文字列リテラルがオブジェクトに対して正しく配置されていないint場合、評価によって*xプログラムが終了する可能性があります。intが 2 バイトより広い場合 (非常に一般的です)、文字*x列リテラルの末尾を過ぎたメモリを参照します。いずれにせよ、*x文字列リテラルを変更しようとすることは明示的に未定義であるため、変更を試みることにはさらに別の種類の未定義の動作があります。

その宣言をコンパイルしたときに、少なくとも警告が表示されるはずです。もしそうなら、あなたは間違いなくそれを無視すべきではありませんでした. 警告が表示されなかった場合は、コンパイラを誘導して警告をさらに生成する方法を見つける必要があります。

TL;DR: そうしないでください。

于 2012-04-28T19:53:14.010 に答える
0

int* x = "5""5"暗黙的に(a const char*)をにキャストし、int*に格納しxます。したがって、は最小値が0x35(文字「5」)で次が0であり、残りが不確定であり、読み取られたときに未定義の動作につながるバイトxを指します。sizeof(int)

于 2012-04-28T19:41:21.583 に答える