2018/02/04

[c/c++]gccでvoid*の演算はwarningにならないの

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 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。