【问题标题】:Why is void pointer arithmetic allowed in gcc?为什么 gcc 中允许使用 void 指针算术?
【发布时间】:2020-02-06 20:58:05
【问题描述】:

虽然void ptr 算术不是标准的,但以下代码是使用 gcc 编译的:

int main(){
 int a = 5;
 void* b = (void*) &a;
 b++;
}

【问题讨论】:

  • 因为 GCC 的开发人员认为这是一个好主意。 GCC 提供了许多其他扩展。有时,当您(意外)使用扩展程序时,您会收到来自 GCC 的通知,但您通常必须请求它。

标签: c sizeof void pointer-arithmetic


【解决方案1】:

这是 GCC 支持的扩展。它将void * 视为char *

来自gcc docs

6.24 void- 和函数指针的算术运算

在 GNU C 中,加法和减法运算支持 指向void 的指针和指向函数的指针。这是由 将 void 或函数的大小视为 1。

这样做的结果是sizeof 也被允许在void 和 函数类型,并返回 1。

【讨论】:

  • 从技术上讲,它是 C 的非标准变体,而不是扩展。在标准 C 中,编译器可以将行为定义为扩展,但它必须提供警告(因为违反了 C 2018 6.5.6 3 中的约束,并且 5.1.1.3 1 需要诊断)。如果你使用-pedantic,GCC 会提供一个警告,然后行为就是一个扩展。 (GCC 不是一个单一的 C 实现;命令行开关产生的每个变体都是一个单独的变体,用于解释 C 标准。)
【解决方案2】:

这是因为最初在 C 中没有类型 void。取而代之的是类型 char 发挥了作用。而sizeof( char ) 等于 1。

例如,我看到了一个非常古老的遗留代码

memset( ( char * )p, 0, n );

其中参数 p 的类型为 int *

看来这样做是为了向后兼容。

【讨论】:

  • 这说明了什么?只要有char * 类型,就不需要使用void * 进行算术运算。您显示的代码不需要使用void * 进行算术运算。哪些代码需要使用void * 进行算术运算才能向后兼容某些东西?什么东西?
猜你喜欢
  • 2012-04-19
  • 2013-01-08
  • 2016-12-15
  • 2021-04-29
  • 2016-09-25
  • 1970-01-01
  • 2023-03-04
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多