2015-08-02 19 views
5

Yanlışlıkla bir işlev adını parantez olmadan yazdırdım ve bir değer yazdırdı. Bunun nasıl olduğunu merak ediyorum. Çıkış, işlev adı veya tanımından bağımsız olarak ve her çalıştırdığımda aynıdır.Neden bir işlev adı yazdırmak bir değer döndürüyor?

DÜZENLEME: Bu okuyor kim cevaplar kimseye, benim şüphe temizlendi - Açıkça eserler, yani int k = (int) foo int fonksiyon adı dönüştürülmesi ;

Bu test kodu şeyler daha açık hale getirecek:

#include <iostream> 
#include <stdio.h> 
#include <conio.h> 
using namespace std; 

void foo(){cout<<'Á';}  //FUNCTION IS NEVER CALLED 

int main() 
{ 
    while(_kbhit())   //JUST TO MAKE SURE BUFFER IS CLEARED 
    { getch();}   //SAME RESULT WITHOUT THESE TWO STATEMENTS 

    cout<<foo;    //OUTPUT 1 
    printf("\n%u", foo); //OUTPUT 4199232 
    /*int k=foo;   //CANNOT CONVERT VOID(*)() TO 'INT'*/ 
    return 0; 
} 
+0

Neden "cout" ile baskı yapıyorsunuz? Printf " –

+0

" printf', typesafe değil. Sadece 'printf' * bir şeyler yapabildiği için, bunun * olması gerektiği anlamına gelmez *. –

cevap

6

Parantez olmadan bir işlev adından söz edildiğinde bir işlev işaretçisi olarak yorumlanır. İşaretçi, tanımlanmamış bir davranış olan ancak çoğu sistemde çalıştığı %u biçim belirteci tarafından unsigned int olarak yorumlanır.

int k = foo nedeninin çalışmadığı bir işlev işaretçisinin normalde int'a dönüştürülecek bir döküm gereksinimi gerektirmesidir. Ancak, printf çok daha hassastır çünkü bağımsız değişken dizesini ayrıştırmak için varargs kullanır; Bağımsız değişkenlerin türünün biçim dizesinde istenen türle eşleştiği varsayılır. foo bir işlev işaretçi

+1

* "Parantez olmadan bir işlev adından söz ediliyor, bir işlev işaretçisi olarak yorumlanır." * En azından C++ 'da biraz yanlış. Örneğin. void (& pf)() = foo; – dyp

+1

"İşaretçi,% u biçim belirticisi tarafından işaretsiz bir int dönüştürülür." Aslında, tanımlanmamış davranış olurdu, değil mi? – juanchopanza

+0

Yep, UB. Güncellenmiş. – Thomas

5

Bu ifade printf("\n%u", foo);printf işlevin foo() adresini geçirir. Böylece basılan değer, bu programın adresi, çalışan programın hafızasındadır.

3
std::cout << foo; 

Çıkışlar 1, çünkü std::cout ile bool dönüştürülür.

adresini yazdırmak için, ihtiyaç açıkça dökme:

printf("\n%u", foo); ile
std::cout << reinterpret_cast<void*>(foo) << std::endl; 

, %u sen unsgigned int dönüştürüldü işlev işaretçisi değeridir gördüklerini unsigned int, bekliyor.

İlgili konular