2014-11-18 15 views
6

Bir Linux Ortamına HP-Unix altında birçok Oracle Pro * C Kodunu geçiriyorum. - ve google ile bir şey bulamadımBu bildirimin kaynağı: main _2a ((argc, argv), int argc, char * argv [])

main _2a((argc,argv), int argc, char * argv[]) 
{ 
... 
} 

Böyle bir decalaration önce hiç görmediğiniz: Bir programda

tanımlanmış ancak böyle bir ana yöntem vardır. Her neyse, işe yarıyor ve gördüğüm şeylerden biri ana işlev olarak kullanılıyor.

Bu konuda bir şey anlatabilecek biri var mı?

Düzenleme: - İyi ipucu makro tanımı vardır:

# define _2a(list,a1,a2)     list a1;a2; 

Hala net bir görünüm yapar (benim için ..)

+3

'_2a', büyük olasılıkla bazı başlık dosyasında tanımlanan bir makrodur. –

+2

Belki '_2a' bir makrodur. –

+0

iyi bir ipucu - bir makro tanımı görebiliyorum. Soruyu güncelliyorum. – Stefan

cevap

6

Biz sadece genişletmek zorundayız makro. Sadece önişlemciyi çağırmak için gcc -E'u kullanabilirsiniz; Ayrıca tüm #include yönergelerini genişletecek, böylece çıktı çirkin olacak.

Ama el ile yapalım. Makro argümanları, ifade değil, token dizileridir.

# define _2a(list,a1,a2)     list a1;a2; 

ve çağırma geçerli::

makro tanımıdır

main _2a((argc,argv), int argc, char * argv[]) 
{ 
... 
} 

argümanları şunlardır:

  • list ->(argc,argv)
  • a1 ->Bu daha yaygın birden fazla satır üzerinde yazılı olacak

    main (argc,argv) int argc; char * argv[]; 
    { 
    ... 
    } 
    

    :

    main(argc, argv) 
    int argc; 
    char *argv[]; 
    { 
        ... 
    } 
    

    Bu eski bir olduğunu -

  • a2 yedek Sahne>char * argv[]

bize verdiği -style işlev bildirimi.C'nin tüm versiyonlarında (2011 standardına kadar olan) hala yasaldır, ancak 1989'dan beri resmen demode olmuştur. Bu eski formun dezavantajı, parametre bilgilerini arayanlara iletmemesidir, bu yüzden bir derleyici Yanlış sayıda argüman türüyle bir işlevi çağırırsanız sizi uyarın.

Ben bir prototip içerir daha modern tanımını genişletiyor _a2 makro alternatif bir tanımı olmasa bahse girerim

, gibi bir şey : O makro tanımı ile

#define _2a(list,a1,a2) (a1, a2) 

, main tanımı yerine bu şekilde genişler :

main (int argc, char * argv[]) 
{ 
... 
} 

Yani _a2 ("a" muhtemelen "argümanı" anlamına gelir) Eğer genişletebilirsiniz kod yazmak sağlayan makro ya, eski tip bir işlev tanımına (ANSI öncesi derleyiciler için) veya bir prototiple modern bir tanıma.

o olurdu uygulamak için makul bir yol:

#ifdef __STDC__ 
#define _2a(list,a1,a2) (a1, a2) 
#else 
#define _2a(list,a1,a2) list a1;a2; 
#endif 

Ama prototip desteklemeyen bir C derleyicisi bulmak çok olası konum beri (onlar dilin standart bir özelliktir oldum Şimdi bir çeyrek asırdır), sadece makronun tamamen kaldırılması ve sadece modern tarzdaki fonksiyon açıklamaları ve tanımlarını kullanması daha mantıklı olacaktır. Ayrıca, main tanımının int dönüş türünde eksik olduğu belirtilmiştir. 1999 C standardından önce, "örtülü int" kuralı altında dönüş türünü atlamak yasaldı. 1999 standardı bu kuralı düşürdü ve açık bir dönüş türü zorunlu kıldı. Çoğu C derleyicisi, varsayılan modlarında hala bir uyarı ile geri dönüş türünün atlanmasına izin verir, ancak atlamak için iyi bir neden yoktur.

+0

Bu, çok fazla bilgi içeren çok iyi yazılmış bir cevaptır. Sadece +1 verebilirim çünkü +2'miz yok - büyük cevabınızı "cevap" olarak kabul etmediğim için çok üzgünüm çünkü Kay'in cevabını zaten işaretledim. Bana ihtiyacım olan bilgileri sağladı ve biraz daha hızlıydı - ayrıca kendi politikam işaretli bir cevabı değiştirmeye izin vermiyor - bunun için üzgünüm. Her neyse, herkese bu cevabı vermeyi çağırıyorum. – Stefan

+0

@Stefan: Soruları yayınladığım nadir durumlarda, genellikle bir cevabı kabul etmeden önce biraz beklerim. (Bu cevabın kabul edilmiş olanın olması gerektiğini söylemem. Bu tamamen size kalmış. BTW, diğer cevabı aldım.) –

+0

Kabul edilen cevabınızı değiştirdiyseniz, rahatsız olmazdım.Genellikle bir ya da iki gün beklerim, bir cevabı kabul etmeden önce, daha fazla ziyaretçi çeker ve bu yüzden de cevaplar da bu yüzden fazladır. :) – kay

8

Bu makro K&R C tarzı fonksiyon tanım görünmesi için kullanılır daha çok "modern" C89 tanımları gibi.

Genişletilmiş kod okur: eski bir yoldur yazmaktır

main(argc, argv) 
    int argc; 
    char *argv[]; 
{ 
    ... 
} 

:

main (argc,argv) int argc;char * argv[]; 
{ 
... 
} 

Ya daha iyi bir girinti ile

int main(int argc, char *argv[]) 
{ 
    ... 
} 
+0

Önişlemcinin ne yaptığını açıklayabilir misiniz? Derleme başlamadan önce hangi yedeklemenin yapıldığını anlamaya çalışıyorum. – Stefan

+0

Düz makro genişletmeyi sorumu içine koydum. Bu sorunuza cevap veriyor mu? – kay

+0

Siz efendim, bir kahramansın! – Stefan

İlgili konular