C/C++编译器如何自动推断某些C函数调用的数组长度?

Joe*_*ing 1 c c++ visual-c++

可能重复:
如何查找sizeof(指向数组的指针)

在第一次调用strcpy_s时,编译器可以推导出数组长度,但在第二次调用中,必须传入数组长度.

TCHAR szTemp[512];
::strcpy_s(szTemp, "a long text message");

TCHAR* pszTemp = new TCHAR[512];
::strcpy_s(pszTemp, 512, "a long text message");
delete []pszTemp;
Run Code Online (Sandbox Code Playgroud)

编译器如何做到这一点?这是Microsoft唯一的扩展吗?另外,我怎么能声明我的方法来利用参数推导?

Eri*_*hil 6

在第一次使用时strcpy_s,数组中元素的数量szTemp是类型的一部分szTemp(因为它是"512的数组TCHAR"),因此编译器知道它并且可以完成声明的模板strcpy_s.

在第二次使用中strcpy_s,pszTemp是一个指针(它是一个"指向"的指针TCHAR),而不是一个数组,并且指向的元素数量不是该类型的一部分.通常,编译器无法知道指针指向的位置有多少个元素.(在这种情况下,编译器可能会推断它,因为上面的代码显示了它,但这会增加编译器和通常被认为不值得实现的语言的复杂性.)

要自己执行此操作,请声明模板的方式strcpy_s:

template <size_t size> errno_t strcpy_s(
    char (&strDestination)[size],
    const char *strSource 
); 
Run Code Online (Sandbox Code Playgroud)

这将声明一个基于参数size的模板,该模板用于一个函数,其第一个参数的类型为"对size元素数组的引用char".当编译器看到使用strcpy_s第一个参数是一个包含512个char元素的数组时,它能够将此参数与模板中的参数匹配,并推断size为512.

在其他地方,您将拥有模板的定义(而不仅仅是声明).该定义可以size在其代码中使用模板参数.当编译器看到使用时strcpy_s,它将在size512 的专门化中实例化模板定义.

这仅适用于C++,而不适用于C,因为C没有模板.