Tanımsız, tanımlanmamış ve uygulama tanımlı davranış


530

C ve C ++ 'da tanımsız davranış nedir? Belirtilmemiş davranış ve uygulama tanımlı davranış ne olacak? Onların arasındaki fark ne?


1
Bu olayı yaptığımızdan oldukça emindim, ama bulamıyorum. Ayrıca bakınız: stackoverflow.com/questions/2301372/…
dmckee --- eski moderatör yavru kedi



1
İşte ilginç bir tartışma ("Ek L ve Tanımsız Davranış" bölümü).
Owen

Yanıtlar:


406

Tanımsız davranış , C ve C ++ dilinin diğer dillerden gelen programcılar için şaşırtıcı olabilecek yönlerinden biridir (diğer diller daha iyi gizlemeye çalışır). Temel olarak, birçok C ++ derleyicisi programda herhangi bir hata rapor etmese bile, öngörülebilir bir şekilde davranmayan C ++ programları yazmak mümkündür!

Klasik bir örneğe bakalım:

#include <iostream>

int main()
{
    char* p = "hello!\n";   // yes I know, deprecated conversion
    p[0] = 'y';
    p[5] = 'w';
    std::cout << p;
}

Değişken pdize değişmezine işaret eder "hello!\n"ve aşağıdaki iki atama bu dize değişmez değerini değiştirmeye çalışır. Bu program ne yapıyor? C ++ standardının 2.14.5. Paragrafına göre, tanımlanmamış davranışı başlatır :

Bir dizgi değişmezini değiştirmeye çalışmanın etkisi tanımlanmamıştır.

İnsanları çığlık duyabiliyorum "Ama bekle, bunu hiçbir sorun derlemeyebilir ve çıktı alabilirim yellow" veya "Ne demek tanımsız, dizgi değişmezleri salt okunur bellekte saklanır, böylece ilk atama denemesi çekirdek dökümü ile sonuçlanır". Bu tam olarak tanımlanmamış davranış sorunudur. Temel olarak, standart, tanımlanmamış davranışları (hatta burun iblisleri) çağırdıktan sonra her şeyin olmasına izin verir. Dilin zihinsel modelinize göre "doğru" bir davranış varsa, bu model yanlıştır; C ++ standardının tek oylama süresi vardır.

Tanımlanmamış davranış diğer örnekleri olarak, sınırlarının ötesinde bir dizi erişim içerir boş işaretçiyi kaldırma , bunların kullanım süresi sona erdikten sonra da nesneleri erişme ya da yazılı olduğu iddia edilen akıllı ifadeler gibi i++ + ++i.

C ++ standardının 1.9 bölümü, tanımlanmamış davranışın daha az tehlikeli iki kardeşini, belirtilmemiş davranışı ve uygulama tanımlı davranışı belirtmektedir :

Bu Uluslararası Standarttaki semantik açıklamalar, parametreleştirilmiş belirsiz bir soyut makineyi tanımlar.

Soyut makinenin belirli yönleri ve işlemleri bu Uluslararası Standartta uygulama tanımlı olarak tanımlanmaktadır (örneğin sizeof(int)). Bunlar soyut makinenin parametrelerini oluşturur. Her uygulama, bu bakımdan özelliklerini ve davranışını açıklayan belgeleri içermelidir.

Soyut makinenin diğer bazı yönleri ve işlemleri bu Uluslararası Standartta belirtilmemiş olarak tanımlanır (örneğin, bir işleve yönelik argümanların değerlendirme sırası). Mümkün olduğunda, bu Uluslararası Standart bir dizi izin verilebilir davranış tanımlar. Bunlar soyut makinenin belirsiz olmayan yönlerini tanımlar.

Bazı diğer işlemler bu Uluslararası Standartta tanımlanmamış olarak tanımlanmıştır (örneğin, boş göstergenin kayıttan çıkarılmasının etkisi). [ Not : bu Uluslararası Standart, tanımlanmamış davranış içeren programların davranışları için herhangi bir gereklilik getirmez. - son not ]

Özellikle, bölüm 1.3.24:

İzin verilen tanımlanamayan davranış durumu öngörülemeyen sonuçlarla tamamen görmezden gelmekten, çeviri veya programın yürütülmesi sırasında ortamın karakteristiği olan (tanı mesajı verilmiş veya verilmeden) belgelenmiş bir şekilde davranmaya, bir çeviriyi veya yürütmeyi sonlandırmaya kadar değişir. bir teşhis mesajı).

Tanımlanmamış davranışa girmekten kaçınmak için ne yapabilirsiniz? Temel olarak, neden bahsettiklerini bilen yazarların iyi C ++ kitaplarını okumalısınız . Vidalı internet öğreticileri. Vida bullschildt.


6
Bu cevabın sadece C ++ 'ı kapsadığı ancak bu sorunun etiketlerinin C'yi içerdiği garip bir gerçektir. C'nin farklı bir "tanımlanmamış davranış" nosyonu vardır: Davranış da belirtilse bile uygulamanın teşhis mesajları vermesini gerektirecektir. belirli kural ihlalleri (kısıtlama ihlalleri) için tanımlanmamış olmak.
Johannes Schaub - litb

8
@Benoit Tanımsız davranış, çünkü standart tanımsız davranış, dönem diyor. Bazı sistemlerde, dize değişmez değerleri salt okunur metin segmentinde saklanır ve bir dize değişmez değerini değiştirmeye çalışırsanız program kilitlenir. Diğer sistemlerde, dizgi değişmezi gerçekten de değişiklik görünecektir. Standart, olması gerekeni zorunlu kılmaz. Tanımsız davranış budur.
fredoverflow

5
@FredOverflow, Neden iyi bir derleyici tanımlanmamış davranış sağlayan kodu derlememize izin veriyor? Bu tür kodları derlemek ne işe yarar ki ? Tanımsız davranışlar veren kodu derlemeye çalışırken neden tüm iyi derleyiciler bize büyük bir kırmızı uyarı işareti vermedi?
Pacerier

14
@Pacerier Derleme zamanında kontrol edilemeyen bazı şeyler vardır. Örneğin, bir boş göstericinin hiçbir zaman kayıttan çıkarılmadığını garanti etmek her zaman mümkün değildir, ancak bu tanımsızdır.
Tim Seguine

4
@Celeritas, tanımsız davranış belirleyici olmayabilir. Örneğin, başlatılmamış belleğin içeriğinin ne olacağını önceden bilmek imkansızdır, örn. int f(){int a; return a;}: aişlevi, işlev çağrıları arasında değişebilir.
Mark

97

Bu temelde standarttan düz bir kopyala yapıştır

3.4.1 1 Her bir uygulamanın seçimin nasıl yapıldığını belgelediği, uygulama tanımlı davranış belirtilmemiş davranış

2 ÖRNEK Uygulama tanımlı davranışa bir örnek, işaretli bir tamsayı sağa kaydırıldığında yüksek dereceli bitin yayılmasıdır.

3.4.3 1 taşınabilir olmayan veya hatalı program yapısı veya hatalı verilerin kullanılması üzerine tanımlanmamış davranış davranışı, bu Uluslararası Standart hiçbir gereklilik getirmez

2 NOT Olası tanımlanamayan davranışlar durumu öngörülemeyen sonuçlarla tamamen görmezden gelmekten, çeviri veya program yürütme sırasında ortamın karakteristik bir şekilde (bir tanılama mesajı vererek veya vermeden) yürütmeye, bir çeviri veya yürütmeyi sonlandırmaya kadar değişir. bir teşhis mesajı verilmesi).

3 ÖRNEK Tanımlanmamış davranışa örnek olarak tamsayı taşması davranışı gösterilebilir.

3.4.4 1 belirtilmemiş davranış belirtilmemiş bir değerin kullanılması veya bu standardın iki veya daha fazla olasılık sağladığı ve herhangi bir durumda seçilen başka bir şart getirmediği başka bir davranış

2 ÖRNEK Belirtilmemiş davranışa bir örnek, bir işleve yönelik argümanların değerlendirilme sırasıdır.


3
Uygulama tanımlı ve belirtilmemiş davranış arasındaki fark nedir?
Zolomon

26
@Zolomon: Tıpkı söylediği gibi: esasen aynı şey, ancak uygulama tanımlı olması durumunda, uygulamanın tam olarak ne olacağını belgelemek (gerekli olmasını sağlamak için) gerekirken, belirtilmemişse uygulamanın belgelendirilmesi gerekmemektedir ya da bir şey garanti.
AnT

1
@Zolomon: 3.4.1 ve 2.4.4 arasındaki farka yansıyor.
sbi

8
@Celeritas: Hiper-modern derleyiciler bundan daha iyisini yapabilir. Verilen int foo(int x) { if (x >= 0) launch_missiles(); return x << 1; }Tanımsız Davranış çağırmak füzeyi yok işlevini çağırmak elbette bu yana, bu çağrıyı yapabilir belirleyebilir bir derleyici launch_missiles()koşulsuz.
supercat

2
Alıntıda belirtildiği gibi, belirtilmemiş davranış genellikle sınırlı sayıda olası davranışla sınırlıdır. Bazı durumlarda, tüm bu olasılıkların verilen bağlamda kabul edilebilir olduğu sonucuna varabilirsiniz, bu durumda belirtilmemiş davranışlar hiç bir sorun değildir. Tanımsız davranış tamamen sınırlanmamıştır (eb "program sabit sürücünüzü biçimlendirmeye karar verebilir"). Tanımsız davranış her zaman bir sorundur.
17'de AnT

60

Belki de kolay ifade etme, standartların titiz tanımından daha kolay olabilir.

uygulama tanımlı davranış
Dil, veri türlerine sahip olduğumuzu söylüyor. Derleyici satıcıları hangi boyutları kullanacaklarını belirtir ve yaptıklarının belgelerini sağlar.

tanımlanmamış davranış
Yanlış bir şey yapıyorsunuz. Örneğin, intuymayan bir değerde çok büyük bir değere sahipsiniz char. Bu değeri nasıl yerleştiriyorsunuz char? aslında bir yolu yok! Her şey olabilir, ama en mantıklı olan şey bu int'in ilk baytını alıp içine koymak olacaktır char. İlk baytı atamak için bunu yapmak yanlıştır, ancak başlık altında olan şey budur.

belirtilmemiş davranış
İlk önce bu ikisinin hangi işlevi yürütülür?

void fun(int n, int m);

int fun1()
{
  cout << "fun1";
  return 1;
}
int fun2()
{
  cout << "fun2";
  return 2;
}
...
fun(fun1(), fun2()); // which one is executed first?

Dil, soldan sağa veya sağdan sola değerlendirmeyi belirtmez! Bu nedenle, tanımlanmamış bir davranış tanımlanmamış bir davranışla sonuçlanabilir veya sonuçlanmayabilir, ancak kesinlikle programınız tanımlanmamış bir davranış üretmemelidir.


@ESKay Bence daha fazla netleştirmek için sorunuzun cevabını düzenlemeye değer :)

çünkü fun(fun1(), fun2());"uygulama tanımlı" davranışı değil mi? Sonuçta derleyici birini mi yoksa diğerini mi seçmeli?

Uygulama tanımlı ve belirtilmemiş arasındaki fark, derleyicinin ilk durumda bir davranış seçmesi gerektiğidir, ancak ikinci durumda bunu yapmak zorunda değildir. Örneğin, bir uygulamanın yalnızca bir tanımına sahip olması gerekir sizeof(int). Yani, sizeof(int)programın bir kısmı için 4, diğerleri için 8 olduğu söylenemez . Derleyicinin Tamam diyebileceği belirtilmemiş davranışların aksine, bu argümanları soldan sağa değerlendireceğim ve bir sonraki işlevin argümanları sağdan sola değerlendirilecek. Aynı programda olabilir, bu yüzden belirtilmemiş olarak adlandırılır . Aslında, belirtilmemiş bazı davranışlar belirtilirse C ++ daha kolay hale getirilebilirdi. Dr.Stustustrup'un bunun cevabına bir göz atın :

Derleyiciye bu özgürlüğü vererek üretilebilecek ile “sıradan soldan sağa değerlendirme” gerektiren farkın önemli olabileceği iddia edilmektedir. İkna olmadım, ama özgürlüğün "dışarıda" sayısız derleyicisinden yararlanarak ve özgürlüğü tutkuyla savunan bazı insanlar, bir değişikliğin zor olacağını ve C ve C ++ dünyalarının uzak köşelerine nüfuz etmesinin on yıllar sürebileceğini söyledi. Ben tüm derleyiciler ++ i + i ++ gibi koda karşı uyarmak hayal kırıklığına uğrattı. Benzer şekilde, argümanların değerlendirme sırası da belirtilmemiştir.

IMO çok fazla "şey" tanımsız, belirtilmemiş, uygulama tanımlı vb. Olarak bırakılmıştır. Ancak, bu söylemesi kolay ve hatta örnekler vermek, ancak düzeltilmesi zor. Ayrıca, sorunların çoğundan kaçınmanın ve taşınabilir kod üretmenin o kadar da zor olmadığı belirtilmelidir.


1
çünkü fun(fun1(), fun2());davranış değil "implementation defined"mi? Sonuçta derleyici birini mi yoksa diğerini mi seçmeli?
Lazer

1
@AraK: açıkladığınız için teşekkürler. Şimdi anlıyorum. Btw, "I am gonna evaluate these arguments left-to-right and the next function's arguments are evaluated right-to-left"bunun olduğunu anlıyorum can. Gerçekten, bugünlerde kullandığımız derleyiciler ile mi?
Lazer

1
@ eSKay Pek çok derleyici ile ellerini kirleten bir guru sormalısınız :) AFAIK VC her zaman sağdan sola argümanları değerlendirir.
AraK

4
@Lazer: Kesinlikle olabilir. Basit senaryo: foo (bar, boz ()) ve foo (boz (), bar), burada bar int ve boz () int döndüren bir fonksiyondur. R0-R1 kayıtlarında parametrelerin geçirilmesinin beklendiği bir CPU olduğunu varsayın. Fonksiyon sonuçları R0 olarak döndürülür; fonksiyonlar R1'i çöpe atabilir. "Boz" u "boz ()" öncesi değerlendirmek, boz () çağrılmadan önce çubuğun bir kopyasının başka bir yere kaydedilmesini ve kaydedilen kopyayı yüklemesini gerektirir. "Boz ()" dan sonra "bar" değerini değerlendirmek bir bellek deposundan kaçınmayı ve yeniden getirmeyi önleyecektir ve birçok derleyicinin argüman listesindeki sıralarına bakılmaksızın yapacağı bir optimizasyondur.
supercat

6
C ++ hakkında bilmiyorum ama C standardı bir int için bir char dönüşüm ya tanımlanmış uygulama (hatta gerçek değerleri ve türlerin imza bağlı olarak) iyi tanımlanmış olduğunu söylüyor. Bkz. C99 §6.3.1.3 (C11'de değişmedi).
Nikolai Ruhe

27

Resmi C Gerekçe Belgesinden

Terimleri belirtilmemiş davranışı, tanımsız davranış ve uygulama tanımlı davranış, özellikleri Standart etmeyen, ya tamamen tarif edemez programları yazma sonucunu kategorilere ayırmak için kullanılır. Bu kategorileştirmeyi benimsemenin amacı, uygulama kalitesinin piyasada aktif bir güç olmasına izin veren uygulamalar arasında belirli bir çeşitliliğe izin vermek ve Standarda uygunluk önbelleğini kaldırmadan belirli popüler uzantılara izin vermektir. Standart F'ye Ek F, bu üç kategoriden birine giren davranışları kataloglar.

Belirtilmemiş davranış , çevirmene programları çevirmede bir miktar enlem verir. Bu enlem, programın tercüme edilemediği kadar uzanmaz.

Tanımsız davranış , uygulayıcıya, teşhis edilmesi zor bazı program hatalarını yakalamaması için lisans verir. Ayrıca, uygun dil uzantısının mümkün olduğu alanları da tanımlar: uygulayıcı, resmi olarak tanımlanmamış davranışın bir tanımını sağlayarak dili artırabilir.

Uygulama tanımlı davranış, bir uygulayıcıya uygun yaklaşımı seçme özgürlüğü verir, ancak bu seçimin kullanıcıya açıklanmasını gerektirir. Uygulama tanımlı olarak belirlenen davranışlar genellikle bir kullanıcının uygulama tanımına dayalı olarak anlamlı kodlama kararları alabileceği davranışlardır. Bir uygulama tanımının ne kadar kapsamlı olması gerektiğine karar verirken uygulayıcılar bu kriteri dikkate almalıdır. Belirtilmemiş davranışlarda olduğu gibi, yalnızca uygulama tanımlı davranışı içeren kaynağı çevirememek yeterli bir yanıt değildir.


3
Hiper-modern derleyici yazarları ayrıca, "tanımsız davranış" ı, programların asla Tanımlanmamış Davranışa neden olacak girdileri almayacağını ve programların bu tür girdileri aldıklarında nasıl davrandığını tüm yönleriyle değiştireceğini varsaymak için derleyici yazarlarına lisans vermek olarak kabul eder.
supercat

2
Fark ettiğim bir diğer nokta: C89, bazı uygulamalarda garanti edilen, ancak diğerlerinde garanti edilmeyen özellikleri tanımlamak için "uzantı" terimini kullanmadı. C89'un yazarları, o zaman geçerli olan uygulamaların çoğunun, sonuçların belirli şekillerde kullanılması dışında imzalı aritmetik ve imzasız aritmetiği aynı şekilde tedavi edeceğini ve imzalı taşma durumunda bile böyle bir tedavinin uygulanacağını; Bununla birlikte, Ek J2'de ortak bir uzatma olarak listelemediler, bu da bana bunu bir uzatma yerine doğal bir durum olarak gördüklerini gösteriyor.
supercat

10

Tanımsız Davranış ve Belirsiz Davranışın kısa bir açıklaması vardır.

Nihai özeti:

Özetle, yazılımınızın taşınabilir olması gerekmedikçe, belirtilmemiş davranışlar genellikle endişelenmemeniz gereken bir şeydir. Tersine, tanımlanmamış davranış her zaman istenmez ve asla gerçekleşmemelidir.


1
İki tür derleyici vardır: aksi açıkça belirtilmedikçe, Standardın Tanımsız Davranış biçimlerinin çoğunu temel alınan ortam tarafından belgelenen karakteristik davranışlara geri düşme olarak yorumlayanlar ve Standardın varsayılan olarak tanımladığı davranışları yalnızca yararlı bir şekilde ortaya koyanlar Uygulama Tanımlı. İlk tip derleyicileri kullanırken, ilk tipteki birçok şey UB kullanılarak verimli ve güvenli bir şekilde yapılabilir. İkinci tip derleyiciler, sadece bu gibi durumlarda davranışı garanti etmek için seçenekler sunarlarsa bu tür görevler için uygun olacaktır.
supercat

8

Tarihsel olarak, hem Uygulama Tanımlı Davranış hem de Tanımsız Davranış, Standart yazarlarının, kalite uygulamaları yazan kişilerin, varsa, hangi uygulama alanında çalışan amaçlanan uygulama alanındaki programlar için karar vereceğini karar vermelerini bekledikleri durumları temsil eder. hedeflenen hedefler. Üst düzey sayı-crunching kodunun ihtiyaçları, düşük seviyeli sistem kodundan oldukça farklıdır ve hem UB hem de IDB, derleyici yazarlarına bu farklı ihtiyaçları karşılamak için esneklik sağlar. Her iki kategori de uygulamaların belirli bir amaç için, hatta herhangi bir amaç için yararlı bir şekilde davranmasını zorunlu kılmaz. Bununla birlikte, belirli bir amaca uygun olduğunu iddia eden kalite uygulamaları, bu amaca uygun bir şekilde davranmalıdır.Standardın gerektirip gerektirmediği .

Uygulama Tanımlı Davranış ve Tanımsız Davranış arasındaki tek fark, ilkinin uygulamanın hiçbir şeyin yararlı olamayacağı durumlarda bile tutarlı bir davranış tanımlamasını ve belgelemesini gerektirmesidir . Aralarındaki ayrım çizgisi, uygulamaların davranışları tanımlamasının genellikle yararlı olup olmayacağı değil (derleyici yazarları, Standardın gerektirip gerektirmediği pratik olduğunda yararlı davranışları tanımlamalıdır) değil, bir davranışın tanımlanmasının aynı anda maliyetli olacağı uygulamalar olup olmadığıdır. ve işe yaramaz . Bu tür uygulamaların var olabileceğine dair bir karar, hiçbir şekilde, tanımlanmış bir davranışın diğer platformlarda desteklenmesinin yararlılığına ilişkin herhangi bir yargı anlamına gelmez.

Ne yazık ki, 1990'ların ortalarından beri derleyici yazarları, davranışsal yetmezliklerin yokluğunu, davranışsal garantilerin hayati oldukları uygulama alanlarında ve hatta neredeyse hiçbir maliyeti olmadığı sistemlerde bile maliyete değmeyeceğine dair bir yargı olarak yorumlamaya başladılar. Derleyici yazarlar UB'ye makul bir yargılama daveti olarak davranmak yerine, bunu yapmamak için bir bahane olarak görmeye başladılar .

Örneğin, aşağıdaki kod verildiğinde:

int scaled_velocity(int v, unsigned char pow)
{
  if (v > 250)
    v = 250;
  if (v < -250)
    v = -250;
  return v << pow;
}

ikinin tamamlayıcı uygulamasının, ifadeyi olumlu ya da olumsuz v << powolup olmadığına bakılmaksızın ikinin tamamlayıcı kayması olarak ele almak için herhangi bir çaba sarf etmesi gerekmez v.

Bununla birlikte, günümüzün derleyici yazarları arasında tercih edilen felsefe, ancak vprogramın Tanımsız Davranışla meşgul olması durumunda negatif olabileceğinden, programın negatif aralığını kırpması için bir neden olmadığını öne sürecektir v. Her bir anlamlı derleyicide desteklenen negatif değerlerin sola kaydırılması ve mevcut kodun büyük bir kısmı bu davranışa dayanmasına rağmen, modern felsefe, Standardın sola kaydırılan negatif değerlerin UB olduğunu söyler. derleyici yazarlarının bunu görmezden gelmesi gerektiğini ima eder.


Ancak tanımlanmamış davranışları güzel bir şekilde ele almak ücretsiz değildir. Modern derleyicilerin bazı UB vakalarında bu kadar tuhaf davranış sergilemelerinin tüm nedeni, acımasızca optimize etmeleridir ve bu konuda en iyi işi yapmak için, UB'nin asla gerçekleşmediğini varsaymaları gerekir.
Tom Swirly

Ama <<negatif sayılar üzerinde UB olması kötü bir küçük tuzak ve bunu hatırlatmak için sevindim!
Tom Swirly

1
@TomSwirly: Maalesef, derleyici yazarları, Standart tarafından zorunlu kılanların ötesinde gevşek davranışsal garantiler sunmanın, Standart tarafından tanımlanmayan herhangi bir şeyden her ne pahasına olursa olsun kodun kaçınılmasını gerektirmesine kıyasla büyük bir hız artışına izin verebileceğini umursamıyorlar. Bir programcı, başka herhangi bir yan etkisi olmadığı sürecei+j>k ek taşmanın olduğu durumlarda 1 veya 0 verimi olup olmadığını umursamıyorsa , bir derleyici, programcı kodu olarak yazarsa mümkün olmayacak bazı büyük optimizasyonlar yapabilir . (int)((unsigned)i+j) > k
supercat

1
@TomSwirly: Onlara göre, X derleyicisi bazı görev T'yi yapmak için kesinlikle uygun bir program alabilir ve Y derleyicisinin aynı programla vereceğinden% 5 daha verimli bir yürütülebilir dosya verebilirse, Y, Y'nin garanti ettiği, ancak X'in desteklemediği davranışlardan yararlanan bir programla aynı görevi üç kez etkili bir şekilde yapan kod üretebilir.
supercat

6

C ++ standardı n3337 § 1.3.10 uygulama tanımlı davranış

iyi biçimlendirilmiş bir program yapısı ve doğru veriler için, uygulamaya ve her bir uygulama belgesine bağlı olarak

Bazen C ++ Standardı bazı yapılara belirli bir davranış getirmez, bunun yerine belirli, iyi tanımlanmış bir davranışın belirli bir uygulama (kütüphane sürümü) tarafından seçilmesi ve tanımlanması gerektiğini söyler . Böylece, Standard bunu tanımlamasa bile, kullanıcı programın nasıl davranacağını tam olarak bilebilir.


C ++ standardı n3337 § 1.3.24 tanımlanmamış davranış

bu standardın hiçbir gereklilik getirmediği davranış [Not: Bu standardın açık bir davranış tanımını atlaması veya bir program hatalı bir yapı veya hatalı veri kullanması durumunda tanımlanmamış davranış beklenebilir. İzin verilen tanımlanamayan davranış durumu öngörülemeyen sonuçlarla tamamen görmezden gelmekten, çeviri veya programın yürütülmesi sırasında ortamın karakteristiği olan (tanı mesajı verilmiş veya verilmeden) belgelenmiş bir şekilde davranmaya, bir çeviriyi veya yürütmeyi sonlandırmaya kadar değişir. bir teşhis mesajı). Birçok hatalı program yapısı tanımlanmamış davranış oluşturmaz; teşhis edilmeleri gerekir. - son not]

Program C ++ Standardına göre tanımlanmamış bir yapı ile karşılaştığında, yapmak istediği her şeyi yapmasına izin verilir (belki bana bir e-posta gönderebilir veya size bir e-posta gönderebilir veya kodu tamamen göz ardı edebilir).


C ++ standardı n3337 § 1.3.25 belirtilmemiş davranış

iyi biçimlendirilmiş bir program yapısı ve uygulamaya bağlı olarak doğru veriler için davranış [Not: Uygulama, hangi davranışın oluştuğunu belgelemek için gerekli değildir. Olası davranışların kapsamı genellikle bu Uluslararası Standart tarafından tanımlanır. - son not]

C ++ Standardı bazı yapılara belirli bir davranış getirmez, bunun yerine belirli bir uygulama (kütüphane sürümü) tarafından belirli , iyi tanımlanmış bir davranışın seçilmesi gerektiğini ( bot gerekli değildir ) söylüyor . Dolayısıyla, herhangi bir açıklama yapılmadığında, kullanıcının programın nasıl davranacağını tam olarak bilmek zor olabilir.


6

Uygulama tanımlı-

Uygulayıcılar iyi belgelenmelidir, standart seçenekler sunar ama derlediğinizden emin olun

Belirtilmemiş -

Uygulama tanımlı ile aynı, ancak belgelenmedi

Tanımsız-

Herhangi bir şey olabilir, onunla ilgilen.


2
Bence "tanımsız" ın pratik anlamının son birkaç yılda değiştiğini belirtmek önemlidir. Eskiden verildiğinde uint32_t s;, 33'ün 1u<<sne zaman değerlendirildiğinin sbelki 0 verim ya da verim 2 vermesi beklenebilirdi, ama tuhaf başka bir şey yapmazdı. Bununla birlikte, daha yeni derleyiciler, 1u<<sbir derleyicinin sönceden 32'den az olması gerektiği için, bu ifadeden önce veya sonra yalnızca s32 veya daha büyük olsaydı ilgili olabilecek herhangi bir kodun atlanabileceğini belirlemesine neden olabilir.
supercat
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.