防止在 C 中编译 void** 指针算法
Preventing compilation of void** pointer arithmetic in C
这与 Pointer arithmetic for void pointer in C 的概念相同,只是我的数据类型是 void**
而不是 void*
#include <stdlib.h>
#include <stdio.h>
int main() {
int foo [] = {1, 2};
void* bar = &foo;
void** baz = &bar;
void** bazplusone = baz + 1;
// cast to void* to make printf happy
printf("foo points to %p\n", (void*)foo);
printf("baz points to the address of bar and is %p\n", (void*)baz);
printf("bazplusone is an increment of a void** and points to %p\n",(void*)bazplusone);
return 0;
}
这导致我的 gcc 版本的输出如下:
foo points to 0x7ffeee54e770
bar is a void* cast of foo and points to 0x7ffeee54e770
baz points to the address of bar and is 0x7ffeee54e760
bazplusone is an increment of a void** and points to 0x7ffeee54e768
我有两个问题:
- 根据 C 标准,这是合法的吗?
- 假设#1 是
false,有没有办法生成编译器错误?两者都不
-pendandic-errors
也不-Wpointer-arith
抱怨这个小
程序
起初我误解了你在做什么。我以为你在 void*
上做数学运算。 C 标准不允许这样做,但 GCC(和 clang)扩展允许将其视为 char*
.
上的数学
但是,您正在对 void**
进行数学运算,这完全没问题。 void*
是指针的大小,不是未定义的值。您可以制作 void*
的数组,并且可以在 void**
上进行指针数学运算,因为它具有定义的大小。
所以你永远不会收到关于 void**
数学的警告,因为这不是问题。
这与 Pointer arithmetic for void pointer in C 的概念相同,只是我的数据类型是 void**
而不是 void*
#include <stdlib.h>
#include <stdio.h>
int main() {
int foo [] = {1, 2};
void* bar = &foo;
void** baz = &bar;
void** bazplusone = baz + 1;
// cast to void* to make printf happy
printf("foo points to %p\n", (void*)foo);
printf("baz points to the address of bar and is %p\n", (void*)baz);
printf("bazplusone is an increment of a void** and points to %p\n",(void*)bazplusone);
return 0;
}
这导致我的 gcc 版本的输出如下:
foo points to 0x7ffeee54e770
bar is a void* cast of foo and points to 0x7ffeee54e770
baz points to the address of bar and is 0x7ffeee54e760
bazplusone is an increment of a void** and points to 0x7ffeee54e768
我有两个问题:
- 根据 C 标准,这是合法的吗?
- 假设#1 是
false,有没有办法生成编译器错误?两者都不
-pendandic-errors
也不-Wpointer-arith
抱怨这个小 程序
起初我误解了你在做什么。我以为你在 void*
上做数学运算。 C 标准不允许这样做,但 GCC(和 clang)扩展允许将其视为 char*
.
但是,您正在对 void**
进行数学运算,这完全没问题。 void*
是指针的大小,不是未定义的值。您可以制作 void*
的数组,并且可以在 void**
上进行指针数学运算,因为它具有定义的大小。
所以你永远不会收到关于 void**
数学的警告,因为这不是问题。