防止C中void**指针算法的编译

防止C中void**指针算法的编译,c,pointers,void-pointers,C,Pointers,Void Pointers,这与概念相同,只是我的数据类型是void**而不是void* #包括 #包括 int main(){ int foo[]={1,2}; void*bar=&foo; void**baz=&bar; void**bazplusone=baz+1; //铸造为空*使printf快乐 printf(“foo指向%p\n”,(void*)foo); printf(“baz指向bar的地址,为%p\n”,(void*)baz); printf(“bazplusone是void**的增量,指向%p\n”,(

这与概念相同,只是我的数据类型是
void**
而不是
void*

#包括
#包括
int main(){
int foo[]={1,2};
void*bar=&foo;
void**baz=&bar;
void**bazplusone=baz+1;
//铸造为空*使printf快乐
printf(“foo指向%p\n”,(void*)foo);
printf(“baz指向bar的地址,为%p\n”,(void*)baz);
printf(“bazplusone是void**的增量,指向%p\n”,(void*)bazplusone);
返回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错误
    -Wpointer-arith
    抱怨这个小错误 节目

  • 我一开始误解了你在做什么。我以为你在做一个
    void*
    上的数学题。这是C标准不允许的,但是GCC(和clang)扩展允许这样做,它将其视为
    char*
    上的数学

    但是,您正在一个
    void**
    上进行数学运算,这完全可以。
    void*
    是指针的大小,不是未定义的值。您可以创建
    void*
    s的数组,并且可以对
    void**
    进行指针数学运算,因为它有一个已定义的大小


    所以你永远不会得到关于数学的警告,因为这不是一个问题。

    我误解了你一开始在做什么。我以为你在做一个
    void*
    上的数学题。这是C标准不允许的,但是GCC(和clang)扩展允许这样做,它将其视为
    char*
    上的数学

    但是,您正在一个
    void**
    上进行数学运算,这完全可以。
    void*
    是指针的大小,不是未定义的值。您可以创建
    void*
    s的数组,并且可以对
    void**
    进行指针数学运算,因为它有一个已定义的大小


    因此,您永远不会收到有关
    void**
    math的警告,因为它不是问题。

    它是一个GCC扩展。我没有试过,但是你试过了吗?
    -std=c11-pedantic
    ?通过我刚写的一个小测试,我得到了一个警告:
    void math.c:7:16:warning:GCCOh的算术[-Wpointer arith]
    中使用的'void*'类型指针,顺便说一句,
    void**
    上的数学是完全合法的。它将指向void*的指针按void*的大小递增。例如,不能有一个
    void
    数组,但可以有一个
    void*
    数组。只要为类型
    t
    定义了
    sizeof(t)
    ,那么
    t*
    上的算术就定义得很好。在这种情况下,
    t
    void*
    。由于定义了它的大小,所以
    void**
    上的算术也是定义良好的。它是一个GCC扩展。我没有试过,但是你试过了吗?
    -std=c11-pedantic
    ?通过我刚写的一个小测试,我得到了一个警告:
    void math.c:7:16:warning:GCCOh的算术[-Wpointer arith]
    中使用的'void*'类型指针,顺便说一句,
    void**
    上的数学是完全合法的。它将指向void*的指针按void*的大小递增。例如,不能有一个
    void
    数组,但可以有一个
    void*
    数组。只要为类型
    t
    定义了
    sizeof(t)
    ,那么
    t*
    上的算术就定义得很好。在这种情况下,
    t
    void*
    。由于它的大小是定义的,那么在
    void**
    上的算术也是定义良好的。“允许”应该改为“定义的”。C标准并不禁止程序员或程序做它没有定义的事情;他们通常是被允许的。并且,如果接受严格一致性程序的C实现接受这样做的程序(比如因为它定义了一个扩展),那么该程序符合C标准的定义。“a
    void*
    是指针的大小”应该说“a
    void*
    有一个已知的大小。”“指针的大小”不是一个固定的数量;在C实现中,不同类型的指针可能有不同的大小。@EricPostpischil算法在
    void*
    值上是一种违反约束的行为,而不仅仅是未定义的行为。一致性实现必须对其进行诊断,并且可以拒绝或接受它。@KeithThompson:是的,它违反了约束。尽管如此,我上面写的句子是正确的。“允许”应该改为“定义”。C标准并不禁止程序员或程序做它没有定义的事情;他们通常是被允许的。并且,如果接受严格一致性程序的C实现接受这样做的程序(比如因为它定义了一个扩展),那么该程序符合C标准的定义。“a
    void*
    是指针的大小”应该说“a
    void*
    有一个已知的大小。”“指针的大小”不是一个固定的数量;在C实现中,不同类型的指针可能有不同的大小。@EricPostpischil算法在
    void*
    值上是一种违反约束的行为,而不仅仅是未定义的行为。一致性实现必须对其进行诊断,并且可以拒绝或接受它。@KeithThompson:是的,它违反了约束。尽管如此,我上面写的句子是正确的。