2015-03-26 27 views
15

İlk önce bazı referanslar.'restrict' anahtar kelimesi - Neden bir dış kısıtlanmış değişkenden iç kısıtlı değişkene atanmasına izin verilir?

bir kısıtlama nitelikli işaretçi üzerinden erişilen bir amacı bu işaretçi ile bir özel bir ilişki vardır: C99 Standard bu konuda restrict bölüm 6.7.3 der. 6.7.3.1'de tanımlanan bu ilişki, o nesneye yapılan tüm erişimlerin, o işaretçinin değerini doğrudan veya dolaylı olarak kullanmasını gerektirir. 117) optimizasyonu teşvik ve dan anlamını değiştirmez bir uyan programı oluşturan tüm ön işleme çeviri birimlerini eleme tüm örneklerini silme için register depolama sınıfı gibi restrict eleme (içinde kullanımını) 'dir amaçlanan (yani gözlemlenebilir davranış. Daha sonra

ve (§6.7.3.1 "restrict Formal tanımı"):

D bir Sınırla gibi bir nesne P tayin için bir araç sağlayan normal bir tanımlayıcının bir beyan olsun nitelikli işaretçi T yazın. D bir blok içinde görünen ve depolama sınıfı extern yoksa

, B blok gösterelim. Bir işlev tanımının bildirimleri listesinde D görünüyorsa, B izin verilen satırını belirtin. Aksi halde, B'un ana bloğunu (ya da bağlantısının ne anlama geldiği ortamının program başlangıcında çağrılan herhangi bir işlevini belirtmesine izin verin) bırakın. Bundan sonraki bölümde,

, bir işaretçi ekspresyon E nesne P ile göre olduğu söylenir halinde P modifiye bir kopyasına işaret ( E arasında değerlendirme öncesinde B yürütülmesinde bir dizi noktasında) Önceden işaret ettiği dizi nesnesi E değerini değiştirir. 119) Not '' temel '' yalnızca işaretçi türündeki ifadeler için tanımlanmıştır. B her bir çalıştırma sırasında

, L P göre &L sahip herhangi lvalue olsun. L, X nesnesinin değerine erişmek için belirtilirse ve X da (herhangi bir yöntemle) değiştirilirse, aşağıdaki gereklilikleri uygulanır: T, kalifiye olmaz. X değerine erişmek için kullanılan diğer tüm değer değişimi da P numaralı adrese sahip olacaktır. X değiştiren her erişim, için, bu alt bölümün amaçları için P'u değiştirmek için de dikkate alınacaktır. P blok B2 ilişkili nesne P2, B2 sonra icra ya B yürütülmesi veya B2 -ecek yürütülmesinden önce başlayacaktır başka sınırlı işaretçi dayanan bir işaretçi ekspresyon E değerini atanırsa ödevden önce bitirmek. Bu gereksinimler karşılanmazsa, davranışı tanımlanmamıştır.

Şimdi
{ 
    int * restrict p1; 
    int * restrict q1; 

    p1 = q1; // undefined behavior 

    { 
     int * restrict p2 = p1; // valid 
     int * restrict q2 = q1; // valid 
     p1 = q2; // undefined behavior 
     p2 = q2; // undefined behavior 
    } 
} 

, benim ilk soru şudur: neden sorun için bir dış kısıtlı işaretçi atamak some have pointed out olarak

, bu (standardından Örnek 4) kurallarını göstermektedir bir iç?

Benim anlayış hiçbir şey net aliasing olan bu yasaklar şudur:

Tabii
int * restricted x = /* ... */ ; 

{ 
    int * restricted y = x; 
    *x = 3; 
    printf("%d\n", *y); // 3 
    *y = 4; 
    printf("%d\n", *x); // 4 
} 

, takma seti iki işaretçiler ile sınırlıdır.

Dolayısıyla benim ikinci soru: (yukarıdaki ilk örnekte, örneğin, yasak p1 = q1;) (izin), ancak iç dış iç dış atanmasıyla fark nedir?

+0

Lütfen, gerçekten derlediğinden, değiştirin. – gnasher729

+0

Bir işaretçiyi parametre listesinde bir işleve 'kısıtlama' olarak bildirebileceğiniz tek yer bu değildi. – fuz

+0

@FUZxxl Hayır, standart böyle söylemez ve tüm uyarılara ve sıkı standart uyumluluğuna sahip olarak mükemmel çalışır. – Norswap

cevap

-4

Bunların hiçbiri tanımlanmamış davranışlar değildir. İstediğiniz gibi kısıtlama işaretçileri arasında atayabilirsiniz. Tanımsız davranışları, yanlış yollarla işaret eden nesnelere yanlış şekilde atarsanız, tanımlanmamış davranışlar oluşabilir.

Ve ikinci örneğinizde, y işareti x'den türetilir, böylece * x'e, sonra * y ile aynı değişkene ilk olarak atanması da iyidir.

Yasalları okumak yerine, aslında “kısıtlamanın” ne elde etmesi gerektiğini düşündünüz mü?

+1

Standart, şüphesiz ki size çelişir. Ve evet bunun hakkında düşündüm; ve sezgisel anlayışımın, standardın söylediği şeyle tam olarak örtüşmediğinden bu soruyu soruyorum. Standartın tam aptallar tarafından yazılmadığı varsayımını yapıyorum ve bu yüzden onun tuhaflıkları için bir sebep olmalı. Ayrıca, bu bir yorumdur; cevap değil. – Norswap

+1

Ad hominemleri dışarıda bırakmak yerine, nerede olduğumu işaret edebilir misiniz? Ayrıca sadece benim okuma değil, aynı zamanda bağlandığım sorudaki diğer stackoverflow kullanıcılarının ve [burada] (http://www.lysator.liu.se/c/restrict.html) de olmadığını göz önünde bulundurun. çelişki (tabii ki, hiçbir şey kanıtlamaz). – Norswap

1

Kuralların iki hedefi karşılamak için tasarlanmıştır düşünüyorum:

  1. benzer bir geçici pointer oluşturulmasına izin ver neyi bir argüman, bir işlev çağrısına geçirildiğinde doğal olarak kullanarak bu kodu gerektirmeden yaratılmış olacaktır işaretçi, fiziksel olarak ayrı bir işleve taşınacaktır.

  2. İşaretçi türetimini gösteren bir grafiğin döngüden arınmış olmasını sağlayın (yani, işaretçi x'in y'den veya doğrudan veya dolaylı olarak y'den türetilen bir şeyden gelmesi durumunda, x'in x'den türetilemediği veya bir dolaylı olarak x) türetilmiştir. Kurallar, # 2'yi elde etmek için kesinlikle gerekli olmaktan daha sıkı olsa da, bu ikinci koşulu yerine getirecek yararlı vakaların neredeyse tamamı, kuralları yazılı olarak yerine getirmekte ve derleyiciler, bu durumun söz konusu olduğu durumlarda, restrict 't.

restrict eleme mükemmel olmaktan uzak, ama yine de çoğu alternatiflerinden daha iyidir.