見ながら:
C コンパイラは、構造体の最初の要素の前にパディングを追加できますか?
次のコードを思いつきました:
(この例ではメモリが解放されていないという事実は無視してください)。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef struct {
char *cstr;
size_t len;
} str_t;
void setStr(str_t* dest, const char* src)
{
size_t len = strlen(src);
dest->cstr = malloc(len + 1);
dest->len = len;
memcpy(dest->cstr, src, len + 1);
}
int main(void)
{
str_t str;
setStr(&str, "woot!");
printf("%s\n", str);
return 0;
}
驚くべきことに、これは実際に機能します。この呼び出し:
printf("%s\n", str);
これと同等のようです:
printf("%s\n", str.cstr);
したがって、次のことも可能であると考えられます。
char* plainstr = malloc(str.len + 1);
strcpy(plainstr, str);
しかし、行きません。とは対照的にprintf
、strcpy
は可変引数ではないため、型チェックがあります。コンパイラは正当に不平を言います:
passing 'str_t' to parameter of incompatible type 'const char *'
しかし、それをキャストすることによって、コンパイラーに「私は本当にそれを意味します」と伝えようとしています:
strcpy(plainstr, (const char*)str);
どちらも機能しません:
operand of type 'str_t' where arithmetic or pointer type is required
以下は機能しないことに注意してください。
strcpy(plainstr, (const char*)&str);
以来str.cstr != &str
。たとえば、この出力:
printf("%p %p\n", str.cstr, &str);
次のとおりです。
0xbdb010 0x7fff788f6ab8
実際、ガベージ データが にコピーされていplainstr
ます。
質問は次のとおりです。
- 構造体をポインター型にキャストできないのはなぜですか?
- キャストが許可されてい
printf
ない場合、これを正しく処理するのはなぜですか?