Tanımlanmamış C ++ davranışı C tanımlı davranışı karşılıyorsa ne olur?


10

*.cppC ++ ile derlediğim bir dosya var (C derleyicisi değil). İçerme işlevi, C'de tanımlandığı anlaşılan bir döküm (son satıra bakın) (bu, yanlışsam lütfen düzeltin!), Ancak bu özel tür için C ++ değil.

[...] C++ code [...]

struct sockaddr_in sa = {0};
int sockfd = ...;
sa.sin_family = AF_INET;
sa.sin_port = htons(port);
bind(sockfd, (struct sockaddr *)&sa, sizeof sa);

[...] C++ code [...]

Bunu bir C ++ dosyasında derlediğim için, şimdi tanımlanmış veya tanımlanmamış bir davranış mı? Yoksa *.ctanımlanmış davranış yapmak için bunu bir dosyaya taşımam gerekir mi?


1
Dosya uzantısının bir anlamı yoktur; yalnızca C veya C ++ olarak derlerseniz.
Fredrik

1
Karşılık gelen tipler birbirinden miras alınmaz ve hiçbir ilişkisi yoktur ve bu C ++ 'da tanımlanmamıştır
Daniel Stephens

1
Genellikle dosyada .cuzantı varsa, C derleyicisi otomatik olarak çağrılır.
Igor

1
C ++ kodunda her zaman bu hile yapmak. Senin için neden işe yaramayacağı hakkında bir fikrim yok. Bir yerde başlık yok mu?
user4581301

3
@DanielStephens Bu program hiçbir zaman işaretçisi kaldırmaya çalışmaz. Döküm kendisine izin verilir , sadece bazen. C tarafı işaretçiyi doğru şekilde gerçek türe çevirirse, her şey yolunda olmalıdır. Bu tiplerin farklı hizalama gereksinimleri varsa döküm ile ilgili sorunlar meydana gelebilir.
user7860670

Yanıtlar:


6

Bu hem C ++ hem de C'de tanımlanır. Sonuçta ortaya çıkan işaretçiyi geri çevirmemesi nedeniyle katı takma düzenlemelerini ihlal etmez.

İşte C ++ 'dan (@interjay ve @VTT sayesinde) alıntı:

Bir nesne işaretçisi, açıkça farklı türde bir nesne işaretçisine dönüştürülebilir.

İşte bunu sağlayan C (teşekkürler @StoryTeller) alıntı :

Bir nesne türüne işaretçi farklı bir nesne türüne işaretçi olarak dönüştürülebilir.

Bunlar, bir işaretçi türünün sonuç olmadan başka bir işaretçi türüne dönüştürülebileceğini (ve sonra isteğe bağlı olarak geri dönüştürülebileceğini) belirtir.

İşte POSIX'in bu özel duruma izin veren alıntısı :

Sockaddr_in yapı İnternet adresi ailesi için adresleri saklamak için kullanılır. Bu tipteki göstergeler soket işlevleriyle kullanım için sockaddr * yapılandırması uygulamaları tarafından kullanılır.

Bu işlev ( bind) C standart kitaplığının bir parçası olduğundan, içeride ne olursa olsun (özellikle, tip döküm işaretçisinin kaydının kaldırılması) tanımlanmamış bir davranış yoktur.


Daha genel soruyu cevaplamak için:

C ve C ++ iki farklı dildir. C ile tanımlanmış ancak C ++ ile tanımlanmamışsa, C ile tanımlanmış ancak C ++ ile tanımlanmamıştır. İki dil arasında hiçbir örtük uyumluluk bunu değiştirmeyecektir. C'de iyi tanımlanmış ancak C ++'da tanımlanmamış bir kod kullanmak istiyorsanız, bu kodu derlemek için bir C derleyicisi kullanmanız gerekir.


1
@interjay Standarttan bir alıntı ile yedekleyebilir misiniz (C veya C ++ iyidir)?
SS Anne


1
@StoryTeller Teşekkürler. Bunun yerine HTTP sürümü eklendi.
SS Anne

2
İkinci argüman - Muhtemelen bu POSIX standardında bir kusurdur bindbir olmalı const void *, ama bindvarlığını öncedir voidC dilinde (ve de C ++ varlığına) 'de. Eklemek için bir noktada güncellediler const, ancak temel türü asla sabitlemediler.
Chris Dodd

1
Bu konuşmayı tavsiye edebilirim youtube.com/watch?v=_qzMpk-22cc Hala cevabı doğrular mı, yoksa tam tersini söylüyor mu emin değilim: -o C ++ bir kabus .. lol
Daniel Stephens

-3

C ve C ++ kodu arasındaki çağrıların tümü, ilgili standartlar açısından Tanımsız Davranışı çağırır, ancak çoğu platform bu tür şeyleri belirtir.

C veya C ++ Standardının bir bölümünün ve bir uygulamanın belgelerinin birlikte bir eylemi tanımladığı veya tanımladığı, ancak diğer bölümlerin Tanımsız olarak nitelendirdiği durumlarda, uygulamaların müşterilerinin ihtiyaçlarına en iyi şekilde hizmet edecek şekilde kod işlemesine izin verilir veya hangi moda uygun olursa olsun, müşteri ihtiyaçlarına kayıtsız kalır. Standardın kendi yetkileri dışındaki konuları dikkate alması, çeşitli amaçlara uygunluk iddiasında bulunan uygulamaların ne zaman ve / veya nasıl anlamlı bir şekilde işlenmesi gerektiğine dair herhangi bir yargı anlamına gelmez, ancak bazı derleyici sahiplerinin yaptığı bir efsaneye abone olmaları gerekir.


Birinci paragraf: "C ve C ++ kodu arasındaki çağrıların tümü Tanımlanmamış Davranışı çağırır" "Tanımlanmamış davranışı çağırma" gibi bir şey olsa bile (ki bu yoktur), bu hala bir anlam ifade etmez.
Yörüngedeki Hafiflik Yarışları

İkinci paragraf: ne söylemeye çalıştığınız hakkında bir fikriniz yok.
Yörüngedeki Hafiflik Yarışları

@LightnessRacesinOrbit Bu cevabın, soruya [dil-avukat] etiketini eklememin bir sonucu olduğunu düşünüyorum. Şimdi daha iyi düşündüm (cevaplar çok gerçek anlamındadır) ve kaldırıldı.
SS Anne

1
@ JL2210 Bunun senin hatan olduğunu sanmıyorum.
Orbit'te Hafiflik Yarışları
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.