【问题标题】:Function headers in cc中的函数头
【发布时间】:2014-11-09 19:44:30
【问题描述】:

假设我有以下功能:

void *mycalloc(size_t num, size_t size, char *file, unsigned int line){
    char *retptr = mymalloc((num * size), file, line); 
    if(!retptr){
        return NULL;
    }
    else{
        header *blk_header = (header *)retptr - 1;
        for(int i=0; i<blk_header->size; i++){
            retptr[i] = 0;
        }
        return retptr; //<-- at this point
    }
}

函数头表示该函数将返回一个 void *,但是我的指针是一个 char *,因此我可以将每个字节设置为 0x00,这是 calloc 所要求的.在返回时将 retptr 强制转换为 void * 会是多余的,还是函数头确定返回的类型?我想我要问的是:这会对期望返回 void * 的调用者造成问题吗?

【问题讨论】:

  • 是的,这将是多余的,因为void * 可以隐式转换为任何非限定对象指针类型。这也会降低可读性,因此实际上是有害的。另外,read this
  • 您可以考虑使用memset 来清零内存。它更有可能被优化,您不必担心不同的指针类型。
  • a void* 在 C 中将在适当时隐式转换为任何指针类型。这就是为什么你不投射malloc的返回值
  • @cHao 真有意思,没听说过
  • @TheParamagneticCroissant:哇,我不得不去看看那个。在使用 C 大约 10 年之后,我不知道这一点。还好我从来没有觉得有必要尝试它......

标签: c return


【解决方案1】:

在返回时将 retptr 强制转换为 void * 会是多余的,还是函数头决定返回的类型?

是的。转换将自动进行。


为了更清楚地了解该主题,您可以考虑以下示例,该示例出于直观原因使用数字数据:

#include <stdio.h>

int get_pi() {
  double pi = 3.14;
  return pi;
}


int main(void) {

  double pi = get_pi();
  printf("%f\n", pi);

  return 0;
}

这将打印 3.000。发生了什么?

在函数内部,我们按照我们应该的方式初始化了double 变量,然后我们返回了它。变量自动得到foo()的返回类型,即int

这意味着double将被转换为int,因此3.14变为3。然后我们将函数的返回值分配给一个double变量,但是十进制数字丢失了,如您在printf().


按照 cHao 的建议:

“你可以考虑使用 memset 来清零内存。它更有可能被优化,你不必担心不同的指针类型。”

void * memset(void * ptr, int value, size_t num);

填充内存块

将 ptr 指向的内存块的前 num 字节设置为指定值(解释为无符号字符)。

看一下例子,看看memset()是如何使用的

/* memset example */
#include <stdio.h>
#include <string.h>

int main ()
{
  char str[] = "almost every programmer should know memset!";
  memset (str,'-',6);
  puts (str);
  return 0;
}

示例来自here,您也可以在其中找到参考。

【讨论】:

  • 谢谢你的例子,它确实让推理变得更容易了
  • 不客气。此外,该示例表明,无论我们想要与否,强制转换都会发生(在示例中,我们希望返回 3.14,但自动转换使这不会发生)。此外,我将按照 cmets 中的建议使用memset 更新我的答案,因为我同意。 @MauricioTrajano
【解决方案2】:

演员阵容将从更“特定”的类型 (char*) 变为更“通用”的类型 (void *)。 这很像从返回double 的函数中返回int。进行了不影响调用者的隐式转换。

但是,如果 char * 是您的函数需要返回的唯一数据类型,则将返回类型设置为 char *

【讨论】:

  • s/implicit cast/implicit conversion/g。根据定义,“演员”是明确的。这并不能回答问题。
猜你喜欢
  • 2012-10-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-06-19
  • 2017-05-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多