以下代码是否根据C99标准定义良好?

时间:2014-01-18 20:21:44

标签: pointers standards c99

几年前,CERT发布了一份关于某些编译器的建议,这些编译器优化了C标准中技术上未定义的指针溢出检查,例如:

/* note: not the code being asked about */
#include <stdint.h>
void fn(uint32_t len) {
  char buffer[BUFLEN];
  if (buffer + len > buffer) { /* not defined if len > BUFLEN! */
    die();
  }
  /* do whatever */
}

在咨询C99标准之后,我现在想知道是否以下代码是明确定义的:

#include <stdlib.h>
#include <stdint.h>
int main() {
  uint32_t *buf = malloc(sizeof(uint32_t) * 20);
  *(buf+10) = 100;
  return *(buf+10);
}

C99标准的相关部分似乎是6.5.6/76.5.6/87.20.3.3/2。我对该标准的阅读表明如下:

  1. 7.20.3.3/2未表明malloc分配的内存被视为数组(cf 7.20.3.1 calloc)。
  2. 根据6.5.6/7,在一个加法表达式中,指向不是数组元素的对象的指针与指向长度为1的数组的第一个元素的指针的行为相同。
  3. 6.5.6/8未定义添加表达式的结果,该表达式将指向一个元素,该元素超过数组对象的最后一个元素。由于6.5.6/7表示在此附加表达式中buf的行为与指向长度为1的数组的指针相同,因此buf+10未定义。
  4. 这是否意味着上面的第二个代码列表是根据C99标准未定义的?

1 个答案:

答案 0 :(得分:1)

从7.20.3开始:

  

如果分配成功,则返回指针,以便可以将其分配给指向任何类型对象的指针,然后用于访问此类对象或此类对象的数组分配空间(直到空间被明确释放。)

(强调我的。)所以我认为你对“malloc会给你一个数组”的部分没问题,一旦你有了,那么其余部分就会出现。