2012-12-12 58 views
1

可能重複:
How to find the sizeof(a pointer pointing to an array)C/C++編譯器如何自動推斷某些C函數調用的數組長度?

在第一次調用到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; 

編譯器如何做到這一點?這是微軟唯一的擴展嗎?另外,我怎麼能聲明我的方法來利用參數推導?

+0

@BoPersson:這個問題不是這個問題的重複,因爲這個問題詢問如何在某些情況下推導大小,而另一個則不是。 –

+2

@Eric - 這是關於數組和指針的區別。同樣的問題。 –

+0

@BoPersson:不,它不是「全部」關於數組和指針的區別。它詢問關於推算規模的問題,而這個問題在另一個問題中沒有被問到,除了排名第四的答案沒有討論這個問題,這並沒有解釋它的例子。 –

回答

6

在第一次使用的strcpy_s,陣列szTemp中的元素數目是szTemp類型的一部分(因爲它是一個「512 TCHAR陣列」),因此編譯器知道它並能完成模板宣佈strcpy_s

在第二使用strcpy_spszTemp是一個指針(它是一個「指針TCHAR」),而不是一個陣列,並且元件的數目指出不是類型的一部分。通常,編譯器無法知道指針指向的地方有多少個元素。 (在這種情況下,編譯器可能會推斷出它,因爲前面的代碼顯示了它,但這會增加編譯器和通常認爲不值得實施的語言的複雜性。)

自己做,申報方式strcpy_s被宣佈爲模板:

template <size_t size> errno_t strcpy_s(
    char (&strDestination)[size], 
    const char *strSource 
); 

本聲明基於參數size模板,該模板是其第一個參數的類型爲「引用的函數到charsize元素的數組「。當編譯器看到strcpy_s的第一個參數是char的512個元素的數組時,它可以將此參數與模板中的參數匹配,並且它推斷size爲512.

其他地方,你將有一個模板的定義(不只是一個聲明)。該定義可以在其代碼中使用模板參數size。當編譯器看到使用strcpy_s時,它將實例化模板定義,其中size爲。

+1

最後一個我能理解的解釋,謝謝。 –

2

根據docsstrcpy_s存在作爲具體功能,也可作爲過載的已知大小的陣列,如szTemp陣列你提供的模板函數。在這種情況下,數組的大小就是函數定義的模板參數。

strcpy_s本身就是微軟的唯一功能,所以模板版本不再是接受指針的版本。

1

首先是使用模板,像這樣:

template <size_t N> 
strcpy_s(char (&dest)[N], char const *source) { 
    // ... 
} 

在模板中,N是傳遞了數組的大小。

在第二種情況下,pszTemp是一個指針而不是數組,因此它不會與模板參數(需要實際數組)匹配,所以您需要顯式傳遞目標大小。

1

在模板功能被使用(doc)第一種情況,所以沒有魔:

template <size_t size> 
errno_t strcpy_s(
    char (&strDestination)[size], 
    const char *strSource 
); // C++ only 
1

它可以推斷爲szTemp數組長度,因爲它被聲明爲一個數組。對於pszTemp,它被聲明爲一個指針,並且無法推斷它的長度。

據說有些第三方的strcpy_s實現,但大部分是微軟的事 - 這是他們努力加強安全漏洞的一部分。

相關問題