簡體   English   中英

為什么函數指針都具有相同的值?

[英]Why do function pointers all have the same value?

例如:

using namespace std;
#include <iostream>

void funcOne() {
}

void funcTwo( int x ) {
}

int main() {

  void (*ptrOne)() = funcOne;
  cout << ptrOne << endl;      //prints 1

  void (*ptrTwo)( int x ) = funcTwo;
  cout << ptrTwo << endl;      //prints 1

  int (*ptrMain)() = main;
  cout << ptrMain << endl;     //prints 1

}

有誰知道這背后的原因? 起初我以為這是因為函數不存在於內存中,因為我從不調用它們,因此它們永遠不會被添加到堆棧中。 但即使是指向main函數的指針的值也會輸出1。

函數指針不會隱式轉換為void * ,這是operator <<重載的內容。

這由C ++11§4.10/ 2中的省略指定:

類型為“指向cv T的指針”的prvalue, 其中T是對象類型,可以轉換為類型為“指向cv void的指針”的prvalue。 將“指向cv T的指針”轉換為“指向cv void的指針”的結果指向T類型的對象所在的存儲位置的開始,就好像該對象是類型T的最派生對象(1.8) (即,不是基類子對象)。 空指針值將轉換為目標類型的空指針值。

函數類型不是對象類型。

而且,你甚至不能使用static_cast來做。 函數和對象可以存在於完全不同的地址空間(這稱為哈佛架構),具有不同大小的指針。 轉換函數指針void * 也許可以用做reinterpret_cast :它的“有條件支持”(C ++ 11§5.2.10/ 8)。 這樣的void *只應用於打印或轉換回原始函數指針類型。

像這樣使用它,或者它將被轉換為bool類型。

cout << reinterpret_cast<void*>(ptrOne) << endl;

C ++中的運算符重載增加了各種令人討厭的復雜性。 (它可以讓你做出很棒的東西 - 但有時它只是令人頭疼。)

正如其他答案中所解釋的,C ++正在對函數指針進行一些自動類型強制。 如果你只是使用好的'C風格的printf你應該得到你期望的結果:

#include <cstdio>

// ...

printf("func1: %p\nfunc2: %p\n", funcOne, funcTwo);

試試這個:

void (*ptrOne)() = funcOne;
cout << reinterpret_cast<void*>(ptrOne) << endl;

void (*ptrTwo)( int x ) = funcTwo;
cout << reinterpret_cast<void*>(ptrTwo) << endl;

int (*ptrMain)() = main;
cout << reinterpret_cast<void*>(ptrMain) << endl;

我認為通常,函數重載規則意味着<<被調用的版本是operator<<(bool) ,這意味着:

cout << ptrOne << endl;

變成:

cout << (ptrOne != NULL) << endl;

這與以下相同:

cout << true << endl;

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM