不兼容的指针分配的技术合法性 [英] technical legality of incompatible pointer assignments

查看:110
本文介绍了不兼容的指针分配的技术合法性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

C11标准ISO/IEC 9899:2011(E)在§6.5.16.1/1中为简单分配规定了以下约束条件:

The C11 standard ISO/IEC 9899:2011 (E) states the following constraints for simple assignments in §6.5.16.1/1:

应满足以下条件之一:

One of the following shall hold:

  • 左侧的操作数具有原子,限定或不限定的算术类型,右侧的操作数具有 算术类型;
  • 左操作数具有结构或联合的原子,合格或不合格版本 类型与权利的类型兼容;
  • 左操作数具有原子,合格或不合格的指针类型,并且(考虑到 左值转换后左操作数将具有的类型)两个操作数均为 指向兼容类型的合格或不合格版本的指针,以及指向的类型 到左边的所有限定词都指向右边;
  • 左操作数具有原子,合格或不合格的指针类型,并且(考虑到 左值转换后,左操作数将具有的类型)一个操作数是一个指针 指向对象类型,另一个是指向合格或不合格版本的指针 无效,并且左侧指向的类型具有指向该类型的所有限定符 在右边;
  • 左操作数是原子,限定或不限定的指针,而右是null 指针常量;或
  • 左边的操作数的类型是atomic,qualified或unqualified _Bool,右边的是指针.
  • the left operand has atomic, qualified, or unqualified arithmetic type, and the right has arithmetic type;
  • the left operand has an atomic, qualified, or unqualified version of a structure or union type compatible with the type of the right;
  • the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) both operands are pointers to qualified or unqualified versions of compatible types, and the type pointed to by the left has all the qualifiers of the type pointed to by the right;
  • the left operand has atomic, qualified, or unqualified pointer type, and (considering the type the left operand would have after lvalue conversion) one operand is a pointer to an object type, and the other is a pointer to a qualified or unqualified version of void, and the type pointed to by the left has all the qualifiers of the type pointed to by the right;
  • the left operand is an atomic, qualified, or unqualified pointer, and the right is a null pointer constant; or
  • the left operand has type atomic, qualified, or unqualified _Bool, and the right is a pointer.

我对双方都是不同于void不兼容类型的指针的情况感兴趣.如果我理解正确,那么它至少应该调用UB,因为它违反了此约束.不兼容类型的一个例子应该是(根据§6.2.7和§6.7.2)intdouble.

I am interested in the case in which both sides are pointers to incompatible types different from void. If I understand correctly, this should at the very least invoke UB, as it violates this constraint. One example for incompatible types should be (according to §6.2.7 and §6.7.2) int and double.

因此,以下程序应被违反:

Therefore the following program should be in violation:

int main(void) {
  int a = 17;
  double* p;
  p = &a;
  (void)p;
}

gcc和clang都警告"-Wincompatible-pointer-types",但不要中止编译(使用-std=c11 -Wall -Wextra -pedantic进行编译).

Both gcc and clang warn about "-Wincompatible-pointer-types", but do not abort compilation (compilation with -std=c11 -Wall -Wextra -pedantic).

类似地,以下程序仅在编译正常时才导致"-Wint-conversion"警告.

Similarly, the following program only leads to a "-Wint-conversion" warning, while compiling just fine.

int main(void) {
  int a;
  double* p;
  p = a;
  (void)p;
}

来自C ++,我希望这些测试用例中的任何一个都需要强制转换才能进行编译.有任何理由使这两个程序都符合标准吗?或者,即使通过显式使用-std=c11而不是-std=gnu11来禁用有趣的GNU C扩展,至少有重要的历史原因支持这种代码样式吗?

Coming from C++, I expected that either of those test cases would require a cast to compile. Is there any reason why either of the programs would be standards-legal? Or, are there at least significant historic reasons for supporting this code style even when disabling the entertaining GNU C extensions by explicitly using -std=c11 instead of -std=gnu11?

推荐答案

-pedantic-errors:

$ gcc -std=c11 -pedantic-errors x.c
x.c: In function ‘main’:
x.c:3:15: error: initialization from incompatible pointer type [-Wincompatible-pointer-types]
   double* p = &a;
               ^

C语:

$ clang -std=c11 -pedantic-errors x.c
x.c:3:11: error: incompatible pointer types initializing 'double *' with an
      expression of type 'int *' [-Werror,-Wincompatible-pointer-types]
  double* p = &a;
          ^   ~~
1 error generated.

在野外,很大一部分(至少可以说)典型的C代码不符合要求,因此-pedantic-errors会导致大多数C程序和库无法编译.

A significant proportion (to say the least) of typical C code in the wild is nonconformant, so -pedantic-errors would cause most C programs and libraries to fail to compile.

这篇关于不兼容的指针分配的技术合法性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆