GCC / G ++ derleyicisinde -pedantic kullanmanın amacı nedir?


136

Bu not şunları söylüyor:

-ansi: derleyiciye ANSI dil seçeneğini uygulamasını söyler. Bu, ANSI standardıyla uyumlu olmayan GCC'nin belirli "özelliklerini" kapatır.

-pedantic: ile birlikte kullanıldığında -ansi, derleyiciye ANSI standardına sıkı sıkıya bağlı kalmasını söyler ve uyumlu olmayan herhangi bir kodu reddeder.

Her şey sırayla:

  • GCC / G ++ derleyicisinin amacı -pedanticve -ansiseçenekleri nedir (yukarıdaki açıklamayı anlayamadım)?
  • Birisi bana bu iki seçeneği kullanmak için doğru koşulları söyleyebilir mi?
  • Ne zaman kullanmalıyım?
  • Onlar önemli mi?

Yanıtlar:


84

GCC derleyicileri, mümkünse her zaman programınızı derlemeye çalışır. Ancak, bazı durumlarda, C ve C ++ standartları belirli uzantıların yasak olduğunu belirtir. Gcc veya g ++ gibi uygun derleyiciler bu uzantılarla karşılaşıldığında tanı koymalıdır. Örneğin, gcc derleyicisinin -pedantic seçeneği, gcc'nin bu gibi durumlarda uyarı vermesine neden olur. Daha katı -pedantic-errorsseçeneğini kullanmak, bu tür tanılama uyarılarını, bu tür noktalarda derlemenin başarısız olmasına neden olacak hatalara dönüştürür. Yalnızca uygun bir derleyici tarafından işaretlenmesi gereken ISO dışı yapılar uyarı veya hata oluşturur.


3
ISO C ve C ++ standartları sadece uzantının herhangi bir uygun programın davranışını değiştirmemesi gerektiğinden "uzantıları yasaklar" dır. Derleyici, uzantıları kullanan herhangi bir programı reddetmek zorunda değildir.
MM

@MM: Bazı derleyiciler yararlı bir kurguyu kabul ederken, diğerleri bunu reddettiğinde, Komitenin "uzlaşmasının" uygun bir uygulamanın, programcıların görmezden gelebileceği bir tanı vermesi gerektiğini ve böylece Komite'nin yapıyı zorunlu kılar veya yasaklar.
Supercat

105

Kodlamamda her zaman kullanıyorum.

-ansiBayrak eşdeğerdir -std=c89. Belirtildiği gibi, GCC'nin bazı uzantılarını kapatır. Ekleme -pedantic, daha fazla uzantıyı kapatır ve daha fazla uyarı oluşturur. Örneğin, 509 karakterden daha uzun bir dize hazır bilginiz varsa, bu konuda -pedanticuyarır, çünkü bu C89 standardının gerektirdiği minimum sınırı aşmaktadır. Yani, her C89 derleyicisi 509 uzunluktaki dizeleri kabul etmelidir; daha uzun kabul etmelerine izin verilir, ancak bilgiçlik yapıyorsanız, bir derleyicinin daha uzun dizeleri kabul etmesine izin verilse ve bilgiçlik uyarıları olmadan GCC de bunları kabul eder.


-ansi bazı GCC uzantılarını kapatırken -pedantic daha fazla uzantıyı kapatır. Görünüşe göre -ansi birinci seviye bir kural, sonra -pedantik daha kısıtlı bir kural. Bu iki seçenek kaldırmak anlamına gelir kodumu Microsoft gibi diğer derleyici ile daha uyumlu olabilir mi?
huahsin68

4
@ huahsin68: az çok. MSVC, diğer ekosistemlerinden oldukça farklı bir derleyicidir, kendi ekosistemine daha fazla uyarlanmıştır ve dışında mevcut değildir. Bir çok şeyi kendi tarzında yapar - standartla aynı değildir. Bununla birlikte, standart üstbilgilerle birlikte kalırsanız, MSVC ve GCC oldukça benzerdir. Bununla birlikte, -std=c89 -pedanticbu, diğer platformlardaki farklı derleyiciler arasında daha kolay hareket edebileceğiniz anlamına gelir. Kullanmaya başlar başlamaz <windows.h>, diğer sistemlerle uyumluluk sorunlu hale gelir.
Jonathan Leffler

2
@slf: Diğer tüm satıcılar gibi (GNU derleyicilerini nakit olarak satmasa da), tescilli özelliklerini kullanmanızı istiyorlar mı? Veya daha genel olarak, uzantıları yararlı olarak gördükleri ve varsayılan olarak etkinleştirilmeleri gerektiğini düşündükleri için.
Jonathan Leffler

1
Değer ne olursa olsun ve JFTR , çoğunlukla kullanmayı bıraktım -pedantic, ancak yeniden etkinleştirdiğimde kodumun çoğu hala TAMAM derliyor (açıkça kullanmayan bir program __int128türleri, vardır ukalalıkla yanlış). Ben GCC ile (benim sevme için) çok gürültülü zaman araya bir sahne olduğunu düşünüyorum -pedantic. Sadece 300 kaynak dosyasını test ettim - bazı kütüphane kodu, bazı komutlar, bazı SO test programları - ve beklenen tek sorun vardı. Şu anda Mac OS X 10.9.2'de GCC 4.8.2 kullanılıyor.
Jonathan Leffler

1
@JonathanLeffler, Evet, pratikte bunun işe yaramayacağı gerçek bir derleyicinin adını sorguluyorum? Böyle bir derleyici bile var mı?
Pacerier

23

-ansi30 yaşındaki göre derlemek için derleyici istekleri eski bir anahtardır C standardının eskimiş revizyonu , 1990: ISO / IEC 9899 , esasen ANSI standardı bir rebranding olan Dil C Programlama X3.159-1989" . Neden eskimiş? Çünkü C90 ISO tarafından yayınlandıktan sonra ISO, C standardizasyonundan sorumluydu ve C90'a yönelik herhangi bir teknik onay ISO tarafından yayınlandı -std=c90.

Bu anahtar olmadan, son GCC C derleyicileri ISO / IEC 9899: 2011'de standartlaştırılmış C diline veya en yeni 2018 revizyonuna uyacaktır .

Ne yazık ki, standartlaştırma belgesinin standart kuruluşlardan bile bulunmadığı eski bir standart revizyona bağlı kalmanın kabul edilebilir olduğuna inanan bazı tembel derleyici satıcıları var.

Anahtarın kullanılması, kodun bu eski derleyicilerde derlenmesini sağlamaya yardımcı olur.


-pedanticİlginç bir tanesidir. Yokluğunda -pedanticspesifik standart istendiğinde bile, GCC yine Cı standart olarak kabul edilebilir olmayan bazı uzantılar sağlayacaktır. Örneğin programı düşünün

struct test {
    int zero_size_array[0];
};

C11 taslak n1570 paragraf 6.7.6.2p1 diyor :

İsteğe bağlı tür niteleyicilerine ve statik anahtar sözcüğüne ek olarak, [ve] bir ifadeyi veya * sınırlayabilir. Bir ifadeyi (bir dizinin boyutunu belirten) sınırlarlarsa, ifade bir tamsayı türüne sahip olacaktır. İfade sabit bir ifadeyse, sıfırdan büyük bir değere sahip olacaktır. [...]

C standardı, dizi uzunluğunun sıfırdan büyük olmasını gerektirir; ve bu paragraf kısıtlamalar içerisindedir ; standart şu 5.1.1.3p1 diyor :

Bir önişleme çeviri birimi veya çeviri birimi, herhangi bir sözdizimi kuralının veya kısıtlamasının ihlali içeriyorsa, davranış açıkça tanımsız veya uygulama olarak belirtilmiş olsa bile, uygun bir uygulama (uygulama tanımlı bir şekilde tanımlanır) tanımladı. Tanılama mesajlarının başka durumlarda üretilmesine gerek yoktur.9)

Ancak, programı derlerseniz, gcc -c -std=c90 pedantic_test.cuyarı yapılmaz.

-pedanticderleyicinin aslında C standardına uymasını sağlar ; şimdi standardın gerektirdiği gibi bir teşhis mesajı üretecektir:

gcc -c -pedantic -std=c90 pedantic_test.c
pedantic_test.c:2:9: warning: ISO C forbids zero-size array zero_size_array [-Wpedantic]
     int zero_size_array[0];
         ^~~~~~~~~~~~~~~

Bu nedenle, maksimum taşınabilirlik için standart revizyonu belirtmek yeterli değildir, ayrıca GCC'nin standardın harfine gerçekten uyduğundan emin olmak için -pedantic(veya -pedantic-errors) kullanmanız gerekir .


Sorunun son kısmı C ++-ansi ile kullanmaktı . ANSI hiçbir zaman C ++ dilini standartlaştırmamıştı - sadece ISO'dan benimsediğinden, bu, "Fransa tarafından standartlaştırılmış İngilizce" demek kadar mantıklı. Bununla birlikte, GCC hala C ++ için, aptalca göründüğü gibi kabul ediyor gibi görünüyor.


4
Dil standardında ek revizyonlar yapıldığını unutmayın. Bugün genellikle derliyorum -std=c11 -Wall -Wextra -Wpedantic -Wconversion.
Davislor

14

Temel olarak, kodunuzu ANSI standardını da uygulayan diğer derleyiciler altında derlemeyi ve hangi kitaplıkları / api çağrılarını kullandığınıza dikkat ederseniz, diğer işletim sistemleri / platformları altında derlemeyi çok daha kolay hale getirecektir.

Birincisi, GCC'nin SPECIFIC özelliklerini kapatır. (-ansi) İkincisi, standarda uymayan herhangi bir şeyden şikayet edecek (sadece GCC'nin belirli özellikleri değil, yapılarınız da.) (-pedantik).


6

Kodunuzun taşınabilir olması gerekiyorsa, gcc uzantıları veya standart olmayan diğer özellikler olmadan derlendiğini test edebilirsiniz. Kodunuz derlendiğinde -pedantic -ansi, teoride, diğer ANSI standart derleyicileriyle Tamam'ı derlemelidir.


4
-pedantictüm uzantıları kapatmaz, bir çift çift alt çizgili öğe bırakır. Bu nedenle, kodunuz derlenirse -pedantic -ansive aynı zamanda diğer uygulamalarda derlenebilir gibi görünüyorsa, o zaman derleneceğini söylemek daha doğru olabilir.
Steve Jessop

3
Çifte alt çizgiden bahsettiniz, bu ilginç. Tam olarak ne demek istiyorsun?
huahsin68

Bir örnek, gcc'nin gcc için iyi olan "__asm ​​__ ()" satır içi montaj kodudur, ancak bu çift alt çizgi şey, bir derleyici standartla uyumlu olsa bile, bir Windows derleyicisi üzerinde çalışmayabilir.

3

Çok sayıda farklı derleyici ile çok çeşitli platformlarda derleneceğini düşündüğünüz kod yazıyorsanız, bu bayrakları kullanmak sadece GCC altında derlenen kodları üretmemenize yardımcı olacaktır.


2
GCC'nin bazı sürümleri altında!
Mohamed Amjad LASRI

1

Diğerleri yeterince cevap verdi. Sık sık uzantılara birkaç örnek eklemek istiyorum:

mainİşlev dönen void. Bu standart tarafından tanımlanmamıştır, yani sadece bazı derleyiciler (GCC dahil) üzerinde çalışır, diğerlerinde çalışmaz. Bu arada int main()ve int main(int, char**)standardın tanımladığı iki imza.

Bir başka popüler uzantı, diğer işlevler içindeki işlevleri bildirebilir ve tanımlayabilir:

void f()
{
    void g()
    {
       // ...
    }

    // ...
    g();
    // ...
}

Bu standart dışı. Bu tür bir davranış istiyorsanız, C ++ 11 lambdas'a göz atın


0

Pedantic, gcc derleyicisinin sadece ANSI uyumlu olmasını değil tüm GNU C uzantılarını reddetmesini sağlar.


1
Bu çok ilgi çekici. GNU C uzantısından bahsediyorsunuz ve bu uzantı ANSI standardında olabilir ve olmayabilir. Bununla ilgili daha fazla bilgi alabilir miyim? Bu uygun kaynağı nereden alabilirim?
huahsin68
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.