Atama operatörünün bir değer getirmesinin faydası nedir?


27

Javascript ve PHP'yi değiştirmek istediğim bir dil geliştiriyorum. (Bununla ilgili herhangi bir sorun göremiyorum. Bu dillerden herhangi birinin geniş bir yükleme tabanına sahip olması gibi değil.)

Değiştirmek istediğim şeylerden biri, atama operatörünü bir atama komutuna dönüştürmek ve döndürülen değeri kullanma yeteneğini ortadan kaldırmaktı.

x=1;          /* Assignment. */
if (x==1) {}  /* Comparison. */
x==1;         /* Error or warning, I've not decided yet. */
if (x=1) {}   /* Error. */

Bunun, C insanlarının çok sevdiği tek satırlık işlevlerin artık işe yaramayacağı anlamına geleceğini biliyorum. (Kişisel deneyimimin ötesinde çok az kanıt ile) bunun gerçekleştiğinin büyük çoğunluğunun gerçekten karşılaştırma işlemi olması gerektiğini düşündüm.

Yoksa öyle mi? Atama operatörünün geri dönüş değerinin pratik olarak yeniden yazılamayan herhangi bir pratik kullanımı var mı? (Böyle bir kavramı olan herhangi bir dil için.)


12
JS ve PHP'nin büyük bir "kurulum tabanı" yok mu?
saat

47
@mri İğnelemeden şüpheleniyorum.
Andy Hunt,

12
Hatırlayabildiğim tek faydalı durum while((x = getValue()) != null) {}. Atama kullanmanız breakveya tekrarlamanız gerekeceğinden değiştirmeler çirkinleşir x = getValue.
CodesInChaos

12
@mri Ooh hayır, bu iki dilin önemli bir yatırım yapmadan önemsiz şeyler olduğunu duydum. JS'yi kullanmakta ısrar eden birkaç kişi benim dilimi gördüğünde, benimkine geçecekler ve bir daha asla === yazmak zorunda kalmayacaklar. Tarayıcı üreticilerinin derhal JS ile birlikte dilimi içeren bir güncelleme yayınlayacağından da eşit derecede eminim. :)
billpg

4
Amacınız mevcut bir dili geliştirmek ve geniş çapta benimsemek niyetindeyseniz, mevcut dille geriye doğru% 100 uyumluluğun iyi olduğunu düşünüyorum. Örnek olarak bkz. TypeScript. Amacınız mevcut dile daha iyi bir alternatif sağlamaksa, o zaman çok daha zor bir probleminiz var. Yeni bir dilin var olan gerçekçi bir sorunu , değişim maliyetini ödemek için mevcut dilden çok daha iyi çözmesi gerekir. Dil öğrenmek bir yatırımdır ve karşılığını vermesi gerekir.
Eric Lippert

Yanıtlar:


25

Teknik olarak, bazı sözde işlemlerin okunabilirliğini arttırırsa, bazı sözdizimsel şekerlerin önemsiz şekilde değiştirilebilse bile korunmaya değer olabilir. Ancak, ifade olarak atama bunun altına girmiyor. Karşılaştırma yerine yazılması tehlikesi, nadiren kullanıldığı anlamına gelir (bazen stil rehberleri tarafından bile yasaklanır) ve ne zaman kullanılırsa iki katına çıkarır. Başka bir deyişle, okunabilirlik faydaları sayı ve büyüklükte küçüktür.

Bunu yapan mevcut dillere bakmak faydalı olabilir.

  • Java ve C # bir ifadeyi atamalarını sürdürür, ancak boolean'leri değerlendirmek için şartlar talep ederek bahsettiğiniz tuzakları temizler. Bu çoğunlukla iyi çalışıyor gibi gözükse de, insanlar zaman zaman bunun if (x)yerine if (x != null)veya if (x != 0)türüne bağlı olarak koşullara izin vermediğinden şikayet ediyorlar x.
  • Python, atamayı ifade yerine uygun bir ifade haline getirir. Bunu değiştirmek için yapılan teklifler zaman zaman python-fikirler posta listesine ulaşıyor, ancak benim öznel izlenimim, bunun nadiren gerçekleştiği ve do-while döngüleri, anahtar ifadeleri, çok hatlı lambdalar gibi diğer "eksik" özelliklere kıyasla her seferinde daha az gürültü ürettiği yönünde. vb.

Ancak, Python Aynı anda birden fazla isimlere atama, bir özel durum sağlar: a = b = c. Bu, eşdeğer bir deyim olarak kabul edilir b = c; a = bve zaman zaman kullanılır, bu nedenle de dilinize eklemeye değer olabilir (ancak bu eklemenin geriye dönük olarak uyumlu olması gerektiği için terlemem.)


5
a = b = cDiğer cevapların gerçekte ortaya çıkmadığını ortaya koymak için +1 .
Leo,

6
Üçüncü bir çözünürlük, atama için farklı bir sembol kullanmaktır. Pascal :=atama için kullanır .
Brian,

5
@Brian: Gerçekten, C # gibi. =ödev, ==karşılaştırma.
Marjan Venema,

3
C # 'da, bir şey C4706 uyarısı if (a = true)atar ( ). C ile GCC aynı şekilde a atar . Bu uyarılar, fazladan parantez seti ile susturulabilir, ancak açıkça atamanın kasıtlı olduğunu belirten cesaretlendirmek için vardır. The test value in a conditional expression was the result of an assignment.warning: suggest parentheses around assignment used as truth value [-Wparentheses]
Bob,

2
@delnan Sadece biraz jenerik yorum, ama "sen boolelerde için değerlendirmek koşulları isteyerek söz hatadır kaldır" gelmesiyle yükselişe geçti - a = true vermez bir Boolean değerlendirmek ve bu nedenle bir hata değil, ama aynı zamanda C # ilgili uyarı yükseltir.
Bob,

11

Atama operatörünün geri dönüş değerinin pratik olarak yeniden yazılamayan herhangi bir pratik kullanımı var mı?

Genel olarak konuşursak, hayır. Bir atama ifadesinin değerine sahip olma fikri, atanan değerdir, yani hem yan etkisi hem de değeri için kullanılabilecek bir ifadeye sahip olduğumuz anlamına gelir ve birçok kişi tarafından kafa karıştırıcı olarak kabul edilir.

Yaygın kullanımlar tipik olarak ifadeleri küçük hale getirmek içindir:

x = y = z;

C # 'da "z, y türüne dönüştür, dönüştürülen değeri y' ye, dönüştürülen değer ifadenin değerine, bunu x türüne dönüştür, x 'e ata" anlamına sahiptir.

Ama zaten zaten bir ifade bağlamında belirsiz yan etkiler alanındayız, bu yüzden bunun için çok az zorlayıcı fayda var.

y = z;
x = y;

Benzer şekilde

M(x = 123);

için steno olmak

x = 123;
M(x);

Yine, orijinal kodda hem yan etkileri hem de değerleri için bir ifade kullanıyoruz ve biri yerine iki yan etkisi olan bir ifade veriyoruz. Her ikisi de koklamak; Her ifade için bir yan etkiye sahip olmaya çalışın ve yan etkileri için değil ifadeleri değerleri için kullanın.

Javascript ve PHP'yi değiştirmek istediğim bir dil geliştiriyorum.

Gerçekten cesur olmak ve bir ödevin bir eşitlik değil bir ifade olduğunu vurgulamak istiyorsanız, tavsiyem: açıkça bir ödev ifadesi yapın .

let x be 1;

Kırmızı olan. Veya

x <-- 1;

veya daha da iyisi:

1 --> x;

Veya daha da iyisi

1 → x;

Bunlardan herhangi birinin karıştırılması kesinlikle mümkün değil x == 1.


1
Programlama dillerinde ASCII olmayan Unicode sembolleri için dünya hazır mı?
billpg

Önerdiğin şeyi sevdiğim kadarıyla, hedeflerimden biri çoğu "iyi yazılmış" JavaScript'in çok az değişiklikle veya hiç değişiklik olmadan taşınabilmesi.
billpg

2
@billpg: Dünya hazır mı? Bilmiyorum - dünya 1964'te Unicode'un icat edilmesinden on yıl önce APL için hazır mıydı? İşte APL'de ilk 40'tan altı sayının rastgele bir permütasyonunu seçen bir program: x[⍋x←6?40] APL kendi özel klavyesini gerektiriyordu, ancak oldukça başarılı bir dildi.
Eric Lippert,

@billpg: Macintosh Programcı Atölyesi, regex etiketleri veya stderr yönlendirmesi gibi şeyler için ASCII olmayan semboller kullandı. Diğer taraftan, MPW, Macintosh'un ASCII olmayan karakterleri yazmayı kolaylaştırma avantajına sahipti. ABD klavye sürücüsünün neden ASCII olmayan karakterleri yazmak için uygun bir araç sağlamadığına dair bazı şaşkınlıkları itiraf etmeliyim. Alt-sayı girişi sadece karakter kodlarına bakmakla kalmaz, birçok uygulamada bile çalışmaz.
supercat

Hm, neden biri "sağa" gibi bir şey atamayı tercih ediyor a+b*c --> x? Bu bana garip görünüyor.
Ruslan,

9

Pek çok dil, Python da dahil olmak üzere bir ifadeden ziyade bir atama yapma yolunu seçiyor:

foo = 42 # works
if foo = 42: print "hi" # dies
bar(foo = 42) # keyword arg

ve Golang:

var foo int
foo = 42 # works
if foo = 42 { fmt.Printn("hi") } # dies

Diğer diller atamalara sahip değildir, ancak kapsamlaştırılmış bağlar, örneğin OCaml:

let foo = 42 in
  if foo = 42 then
    print_string "hi"

Ancak, letbir ifadenin kendisidir.

Atamaya izin vermenin avantajı, koşullu içindeki bir işlevin dönüş değerini doğrudan kontrol edebilmemizdir, örneğin bu Perl parçacığında:

if (my $result = some_computation()) {
  say "We succeeded, and the result is $result";
}
else {
  warn "Failed with $result";
}

Perl ayrıca beyanı yalnızca bu şartlı için kapsamlaştırır, bu da onu çok faydalı kılar. Ayrıca orada bir yeni değişken tanımlamaksızın bir koşullu içine atarsanız if ($foo = $bar)uyarır, uyarmaz, uyarmaz if (my $foo = $bar).

Ödevi başka bir ifadede yapmak genellikle yeterlidir, ancak kapsam belirleme sorunları getirebilir:

my $result = some_computation()
if ($result) {
  say "We succeeded, and the result is $result";
}
else {
  warn "Failed with $result";
}
# $result is still visible here - eek!

Golang, hata kontrolü için dönüş değerlerine büyük ölçüde güvenmektedir. Bu nedenle, koşullu bir başlatma ifadesi almasına izin verir:

if result, err := some_computation(); err != nil {
  fmt.Printf("Failed with %d", result)
}
fmt.Printf("We succeeded, and the result is %d\n", result)

Diğer diller, bir koşul içinde boolean olmayan ifadelere izin vermemek için bir tür sistemi kullanır:

int foo;
if (foo = bar()) // Java does not like this

Tabii ki bir boole döndüren bir işlev kullanılırken başarısız oluyor.

Kazara görevlendirmeye karşı savunmak için farklı mekanizmalar gördük:

  • İfade olarak atamaya izin verme
  • Statik tip kontrolü kullan
  • Atama mevcut değil, sadece letbağlarımız var
  • Başlatma ifadesine izin ver, aksi halde atamaya izin verme
  • Bir şartlı içinde bildirmeden atama atama

Onları artan tercih sırasına göre sıraladım - ifadelerin içindeki atamalar yararlı olabilir (ve açık bir bildirim sözdizimine ve farklı bir adlandırılmış argüman sözdizimine sahip olarak Python'un sorunlarını aşmak kolaydır). Fakat aynı etkiye birçok seçenek olduğu için onlara izin vermemeliyiz.

Hatasız kod, kısa koddan daha önemlidir.


"İfade olarak atamasına izin verme" için +1. Bir ifade olarak atama kullanımları, hatalar ve okunabilirlik sorunları için potansiyeli haklı çıkarmaz.
karıştırmak

7

“Kişisel deneyimimin ötesinde çok az kanıtla) bunun gerçekleştiğinin büyük çoğunluğunun gerçekten karşılaştırma operasyonu olarak tasarlandığını düşündüm.

SORUNU SORMAK neden olmasın?

= Atama için ve == eşitlik testi için neden kullanmayın: = atama için ve = (veya hatta ==) eşitlik için?

Gözlemek:

if (a=foo(bar)) {}  // obviously equality
if (a := foo(bar)) { do something with a } // obviously assignment

Programcının eşitlik atamasını yanlış yapmasını zorlaştırmak istiyorsanız, daha da zorlaştırın.

Aynı zamanda, sorunu GERÇEKTEN çözmeyi isteseydiniz, booleanların sadece önceden tanımlanmış sembolik şeker isimleri olan tamsayılar olduğunu iddia eden C güveçini kaldırırdınız. Onları tamamen farklı bir tür yapın. Sonra, yerine

int a = some_value();
if (a) {}

programlayıcıyı yazmaya zorlarsınız:

int a = some_value();
if (a /= 0) {} // Note that /= means 'not equal'.  This is your Ada lesson for today.

Gerçek şu ki, bir operatör olarak atama çok yararlı bir yapıdır. Jiletleri ortadan kaldırmadık çünkü bazı insanlar kendilerini kestiler. Bunun yerine, King Gillette güvenlik bıçağını icat etti.


2
(1) :=görevlendirmek ve =eşitlik için bu sorunu çözebilir, ancak küçük bir ana akım olmayan dil seti kullanarak yetişmeyen her programcının yabancılaştırılması pahasına. (2) Koşullarda izin verilen boollar dışındaki tipler her zaman bool ve tamsayıların karıştırılmasından dolayı değildir, diğer tiplere doğru / yanlış bir yorum vermek yeterlidir. C'den sapmaktan korkmayan daha yeni bir dil, bunu tam sayılar dışındaki birçok tür için yaptı (örn. Python, boş koleksiyonları yanlış görür).

1
Jiletle ilgili olarak: Keskinlik gerektiren bir kullanım durumu. Öte yandan, programlama konusunda iyi değilim, ifade değerlendirmesinin ortasında değişkenlere atanmayı gerektiriyorum. Vücut kıllarının keskin kenarlar olmadan kaybolması için basit, düşük teknolojili, güvenli ve uygun maliyetli bir yöntem olsaydı, jiletlerin yerinden çıkacağından ya da en azından çok daha nadir yapıldığından eminim.

1
@delnan: Bilge bir adam bir keresinde "Mümkün olduğunca basit, ama daha basit olmasın" dedi. Amacınız, a = b - a == b hatalarının büyük çoğunluğunu ortadan kaldırmaksa, koşullu testlerin alanını boolilere sınırlamak ve <other> -> boolean için varsayılan tür dönüştürme kurallarını ortadan kaldırmak size neredeyse Orada. Bu noktada, eğer (a = b) {} yalnızca a ve b hem booleansa hem de a yasal bir değerse, sözdizimsel olarak yasal ise.
John R. Strohm

Atama yapmak, en azından önerdiğiniz değişikliklerden daha tartışmasız olarak bile basittir ve en azından mümkün olduğu kadar basittir - tartışmasız daha da fazla ( if (a = b)a, boolean a, b değeri için bile izin vermez ). Statik yazmadan bir dilde, ayrıca çok daha iyi hata mesajları verir (ayrıştırma zamanında ve çalışma zamanında). Ayrıca, "a = b vs. a == b hatalarının" önlenmesi tek ilgili amaç olmayabilir. Mesela, kodun if items:demek istediği gibi izin if len(items) != 0vermesini ve boolean'ların şartlarını kısıtlamak için vazgeçmem gerektiğini de istiyorum.

1
@delnan Pascal ana olmayan bir dil mi? Milyonlarca insan Pascal (ve / veya Pascal'dan türeyen Modula) kullanarak programlama öğrendi. Ve Delphi hala birçok ülkede yaygın olarak kullanılmaktadır (belki de sizinkilerde çok fazla değildir).
saat

5

Aslında soruyu yanıtlamak için, evet, biraz niş olsalar da, bunun sayısız kullanımı var.

Örneğin, Java’da:

while ((Object ob = x.next()) != null) {
    // This will loop through calling next() until it returns null
    // The value of the returned object is available as ob within the loop
}

Gömülü atama kullanmadan alternatif ob, döngünün kapsamı dışında tanımlanmış ve x.next () öğesini çağıran iki ayrı kod konumu gerektirir.

Tek adımda birden fazla değişken atayabileceğiniz belirtildi.

x = y = z = 3;

Bu tür şeyler en yaygın kullanımdır, ancak yaratıcı programcılar her zaman daha fazlasını bulacaktır.


Bu, döngü koşulu obher döngüde serbest bırakıp yeni bir nesne yaratırken mi?
user3932000

@ user3932000 Bu durumda muhtemelen değil, genellikle x.next () bir şey üzerinde yineleniyor. Olsa da kesinlikle mümkündür.
Tim B,

1

Eğer tüm kuralları telafi etmek olsun, neden şimdi atama bir değer çevirmek için izin ve sadece değil koşullu adımlarla içeri atamalara izin? Bu, başlatma işlemini kolaylaştırmak için ortak bir kodlama hatasını önlemeye devam ederken, sözdizimsel şekeri verir.

Başka bir deyişle, bunu yasal hale getirin:

a=b=c=0;

Ancak bunu yasa dışı kılın:

if (a=b) ...

2
Bu oldukça geçici bir kural gibi görünüyor. Atama yapmak bir ifade vermek ve izin vermek için genişletmek a = b = cdaha dik ve daha kolay uygulanıyor gibi görünüyor. Bu iki yaklaşım, ifadelerdeki ( a + (b = c)) ifadelere katılmamaktadır , ancak bunların üzerinde taraf almadınız, bu yüzden önemli olmadığını varsayıyorum.

"uygulaması kolay" çok fazla dikkate alınmamalıdır. Bir kullanıcı arayüzü tanımladınız - önce kullanıcıların ihtiyaçlarını koyun. Bu davranışın kullanıcıyı engelleyip engellemediğini kendinize sormanız yeterlidir.
Bryan Oakley

Örtülü dönüşüme izin vermemeniz durumunda, koşulların yerine getirilmesi konusunda endişelenmenize gerek yoktur
cırcır ucube

Uygulaması daha kolay, benim argümanlarımdan sadece biriydi. Gerisi ne olacak? Kullanıcı Arabirimi açısından, IMHO tutarsız tasarımının ve geçici istisnaların, genellikle kullanıcının kuralları gizlemesine ve içselleştirmesine engel olduğunu ekleyebilirim.

@ ratchetfreak hala gerçek bools atama konusunda bir sorun olabilir
jk.

0

Onun sesleriyle, oldukça katı bir dil yaratma yolundasınız.

Bunu akılda tutarak, insanları yazmaya zorlamak:

a=c;
b=c;

yerine:

a=b=c;

İnsanların yapmalarını engellemek için bir gelişme olabilir:

if (a=b) {

yapmak istedikleri zaman:

if (a==b) {

fakat sonunda, bu tür hataların yasal kod olup olmadığına dair tespit edilmesi ve uyarılması kolaydır.

Bununla birlikte, aşağıdakileri yapan durumlar vardır:

a=c;
b=c;

anlamına gelmez

if (a==b) {

doğru olacak.

C aslında c () fonksiyonuysa, her çağrıldığında farklı sonuçlar verebilir. (aynı zamanda hesaplama açısından da pahalı olabilir ...)

Aynı şekilde c hafıza haritalandırılmış donanımı gösterici ise,

a=*c;
b=*c;

Her ikisinin de farklı olması muhtemeldir ve ayrıca her okumadaki donanım üzerinde elektronik etkileri olabilir.

Hangi hat adreslerinin okunup okunacağı, belirli zamanlama kısıtlamaları altında ya da altında yazılan, aynı satırda birden fazla atama yapmanın hızlı, basit ve açık olduğu zamanlama riskleri olmadan kesin olarak ihtiyaç duymanız gereken, donanımla ilgili başka birçok izin vardır. geçici değişkenler tanıtmak


4
Eşdeğer a = b = cdeğil a = c; b = c, öyle b = c; a = b. Bu engeller yan etkilerinden çıkışların çoğaltılması ve aynı zamanda değiştirilmesini tutar ave baynı sırada. Ayrıca, bu donanımla ilgili tüm argümanlar aptalcadır: Çoğu dil sistem dili değildir ve bu sorunları çözmek için tasarlanmamıştır ve bu sorunların ortaya çıktığı durumlarda kullanılmazlar. Bu, JavaScript ve / veya PHP'yi değiştirmeyi deneyen bir dil için iki katına çıkar.

delnan, mesele bu değildi, tartışmalı örnekler, onlar. Mesele hala, a = b = c yazmanın yaygın olduğu yerlerin türlerini gösterdikleri ve OP'nin istediği gibi donanım durumunda iyi bir uygulama olduğu düşünülebilir. Eminim onların beklenen ortamla olan ilgilerini değerlendirebilecekler
Michael Shaw

Geriye dönüp baktığımda, bu cevabımla ilgili sorunum öncelikle sistem programlama kullanım durumlarına odaklanmasından kaynaklanıyor (bu, yeterince kötü olmasına rağmen, yazıldığı gibi), ancak yanlış bir yeniden yazmayı varsaydığına dayanıyor. Örnekler a=b=c, ortak / yararlı olan yerlere örnek değildir, sıra ve yan etkilere dikkat edilmesi gereken yerlere örnektir. Bu tamamen bağımsız. Zincirleme atamasını doğru şekilde yeniden yazın ve her iki değişken de aynı derecede doğru.

@delnan: Değer b, bir sıcaklıkta türüne dönüştürülür ve bu, abaşka bir sıcaklıkta türüne dönüştürülür . Bu değerlerin gerçekte kaydedildiği zamanın göreli zamanlaması belirtilmemiş. Dil tasarım perspektifinden bakıldığında, çoklu atama ifadesindeki tüm değerlerin eşleştirme türüne sahip olmasını talep etmenin ve bunların hiçbirinin uçucu olmamasını gerektirmesinin makul olacağını düşünüyorum.
supercat,

0

Atama yaptırma aklımın en büyük yararı, bir ifade olmaktır, hedeflerinizden biri "her şey bir ifadedir" - özellikle LISP'nin bir hedefi ise, gramerinizin daha basit olmasına olanak vermesidir.

Python buna sahip değil; ifadeleri ve ifadeleri vardır, atama ifadesidir. Ancak Python, bir lambdaformu tek bir parametreli ifade olarak tanımladığından , bir lambda içindeki değişkenleri atayamazsınız. Bu zaman zaman elverişli değildir, ancak kritik bir mesele değildir ve bu, Python'da bir ifade vermenin benim deneyimimdeki tek dezavantajı ile ilgilidir.

Atama ya da atama etkisinin, if(x=1)C'nin sahip olabileceği kaza potansiyelini ortaya koymadan ifade etmesine izin vermenin bir yolu , kendi dilinizde olduğu gibi LISP benzeri bir letyapı kullanmaktır . Sözlüksel bir kapsam oluşturmayı tanımlarsanız, bu yolu kullanarak teknik olarak dilinizde hiç bir şekilde görevlendirmenize gerek yoktur . Bu şekilde tanımlanırsa, bir yapı, iç içe geçmiş bir kapatma işlevini argümanlarla oluşturmak ve çağırmakla aynı şekilde derlenebilir.(let ((x 2) (y 3)) (+ x y))5letletlet

Öte yandan, sadece if(x=1)durumla ilgileniyorsanız , ancak C'deki gibi bir ifade olarak atamak istiyorsanız, belki sadece farklı belirteçleri seçmek yeterli olacaktır. Atama: x := 1veya x <- 1. Karşılaştırma: x == 1. Sözdizimi hatası: x = 1.


1
letTeknik olarak yeni bir değişkeni yeni bir kapsamda tanıtmaktan daha fazla şekilde atamaktan farklıdır. Yeni başlayanlar için, letgövdenin dışındaki kod üzerinde hiçbir etkisi yoktur ve bu nedenle atama-ağır kodda önemli bir dezavantajı olan tüm kodun (değişkeni kullanması gereken) daha fazla iç içe geçmesini gerektirir. Eğer biri o rotadan aşağı set!inerse, daha iyi Lisp analogu olurdu - karşılaştırmanın aksine tamamen iç içe geçme veya yeni bir kapsam gerektirmez.

@delnan: Yeniden atamayı yasaklayacak, ancak yeniden düzenlemeye izin verecek, yeniden düzenlemeye izin verecek, (1) yeniden tanımlamanın yalnızca beyan ve tayin tanımlayıcıları için yasal olacağı kurallara tabi olan bir kombinasyon bildir ve ata sözdizimi görmek istiyorum. ) yeniden düzenleme, tüm çevreleyen kapsamlardaki bir değişkeni "reddeder". Bu nedenle, herhangi bir geçerli tanımlayıcının değeri, bu adın önceki bildiriminde atanmış olan olurdu. Bu, sadece birkaç satır için kullanılan değişkenler için kapsam blokları eklemek veya her geçici değişken için yeni isimler formüle etmek zorunda kalmaktan biraz daha hoş görünüyor.
supercat

0

Bunun, C insanlarının çok sevdiği tek satırlık işlevlerin artık işe yaramayacağı anlamına geleceğini biliyorum. (Kişisel deneyimimin ötesinde çok az kanıt ile) bunun gerçekleştiğinin büyük çoğunluğunun gerçekten karşılaştırma işlemi olması gerektiğini düşündüm.

Aslında. Bu yeni bir şey değil, C diline ait tüm güvenli alt kümeler zaten bu sonucu verdi.

MISRA-C, CERT-C ve benzeri tüm koşullar altında yasaklanması, sadece tehlikeli olduğu için.

Koşullar içinde atamaya dayanan kodun yeniden yazılamadığı bir durum yoktur.


Ayrıca, bu tür standartlar değerlendirme sırasına dayanan kod yazmaya karşı da uyarır. Tek bir satırda birden fazla atama x=y=z;böyle bir durumdur. Birden fazla atamaya sahip bir satır yan etkiler içeriyorsa (çağıran işlevler, değişken değişkenlere erişme vb.), İlk önce hangi yan etkinin olacağını bilemezsiniz.

İşlenenlerin değerlendirilmesi arasında dizi puanı yoktur. Bu nedenle, alt ifadenin yönce veya sonra değerlendirilip değerlendirilmediğini bilemeyiz z: C'de belirtilmemiş bir davranıştır. Bu nedenle, bu tür bir kod potansiyel olarak güvenilir değildir, taşınabilir değildir ve C'nin belirtilen güvenli alt kümelerine uygun değildir.

Çözüm kodu ile değiştirmek olurdu y=z; x=y;. Bu bir sıra noktası ekler ve değerlendirme sırasını garanti eder.


Bu nedenle, C'nin neden olduğu tüm sorunlara dayanarak, herhangi bir modern dil, hem koşullar içinde atamayı yasaklamanın yanı sıra, hem de tek bir satırda birden fazla atamanın yapılmasına iyi gelir.

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.