2012-06-18 28 views
7

Bir arkadaşımın bana gönderdiği bazı kodlara bakıyordum ve dedi ki: "Derler, ama işe yaramıyor".Parantez olmadan işlevleri kullandığımda C++ derleyicisi neden şikayet etmiyor?

void foo(){ 
    cout<< "Hello world\n"; 
} 

int main(){ 
    foo; //function without parentheses 
    return 0; 
} 

ilk ben "kullanım parantez, etmelisin" olduğunu söyledi: Ben o parantez olmadan böyle bir şey fonksiyonları kullandığını gördük. Ve sonra bu kodu test ettim - derleme yapar, ancak çalıştırıldığında çalışmaz (hayır "Merhaba dünya" gösterilir).

Peki, neden derler (derleyici GCC 4.7'dan hiç uyarı almaz), ancak çalışmıyor?

+0

Aslında işe yarıyor. foo, olduğu gibi bir işlev işaretçisi olarak ele alınır. 'Foo;' satırı, etkili olmayan bir çizgidir. Uyarılarınızı maksimum değere çevirirseniz, geçerli olmayan bir bildirimle ilgili bir uyarı almanız gerekir. – RedX

+0

Görüyorum * "uyarı: ifade," foo "işlevini çağırmak için değil, bir referanstır * ve *" uyarı: ifadesinin bir etkisi yoktur "*. Muhtemelen -Wall-Wextra – Flexo

+3

ile derlemek istiyorsunuz. (#include 've örneklemizi tamamlayabilmeniz için herhangi bir ad alanı içeriğine koymaya değer) – Flexo

cevap

12

Uyarı seviyesini yeterince yükseğe ayarlarsanız, kesinlikle uyarır.

İşlev adı, işlevin adresini değerlendirir ve yasal bir ifadedir. Genellikle, bir işlev işaretçisi olarak

void (*fptr)() = foo; 

kaydedilir ancak bu gerekli değildir.

11

Kullandığınız uyarı düzeyini artırmanız gerekir. foo; geçerli bir ifade ifadesidir (bir işlevin adı, adlandırılmış işlevin bir işaretçisine dönüştürür) ancak hiçbir etkisi yoktur.

Ben genellikle -std=c++98 -Wall -Wextra -pedantic kullanmak veren:

<stdin>: In function 'void foo()': 
<stdin>:2: error: 'cout' was not declared in this scope 
<stdin>: In function 'int main()': 
<stdin>:6: warning: statement is a reference, not call, to function 'foo' 
<stdin>:6: warning: statement has no effect 
3
foo; 

Burada işlevini 'kullanarak' aslında değiliz. Sadece adresini kullanıyorsun. Bu durumda, onu alıyorsunuz ama gerçekten kullanmıyorsunuz.

Bazı işlevler için bu işlevi bir geriçağırım olarak iletmek istediğinizde işlevlerin adresleri (yani, adları parantez olmadan) yararlıdır.

İlgili konular