lmdbを使っていて、何気なく自分でコーディングしていて気になることがあった。
mdb_get()などでデータを取得すると、MDB_val型に結果が入っている。
構造体の中身は、mv_sizeとmv_dataで、mv_sizeにはmv_dataのデータ長が入っている。
使うときはmv_dataをキャストするなりコピーするなりしていたのだが、バイトデータを扱うことがあってmv_dataに足し算をしていた。
しかし、特に何も言われなかったので、char*なりuint8_t*なりの型になってるのだろうと思い込んでいた。
が、調べてみるとvoid*型だったのだ。
あれ、C言語ってvoid*型に直接演算することができるんだっけ??
試しに、こういうコードを書いた。
01: #include <stdio.h>02: 03: int main(void) 04: { 05: char str[20] = "abcdef"; 06: void *p = str; 07: char *s = p + 3; 08: *s = 'D'; 09: printf("%s\n", str); 10: printf("str=%p\n", &str); 11: printf("p =%p\n", p); 12: printf("s =%p\n", s); 13: 14: return 0; 15: }
$ gcc --version
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.6) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.$ gcc -Wall -Wextra -o tst voidptr.c
$ ./tst
abcDef
str=0x7fffe31467e0
p =0x7fffe31467e0
s =0x7fffe31467e3
やはりwarningも出ない。
昔は出ていたような気がするのだが、自分の記憶は当てにならんし、振り返っても意味が無かろう。
https://stackoverflow.com/questions/3922958/void-arithmetic
`-pedantic`を付けると、警告するそうだ。
$ gcc -pedantic voidptr.c
voidptr.c: In function ‘main’:
voidptr.c:7:17: warning: pointer of type ‘void *’ used in arithmetic [-Wpointer-arith]
char *s = p + 3;
^
voidptr.c:10:12: warning: format ‘%p’ expects argument of type ‘void *’, but argument 2 has type ‘char (*)[20]’ [-Wformat=]
printf("str=%p\n", &str);
^
なるほど。
-pedanticを付けた方が私の認識に近いといえば近いのだが、そんなにC言語の定義に詳しいわけでもないし、他のコンパイラにする予定も無いのであれば、このまま「知っているが放置する」というのがよいかもしれん。
悩ましいですな。
0 件のコメント:
コメントを投稿
コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。
注: コメントを投稿できるのは、このブログのメンバーだけです。