2011-08-15 22 views
13

Aşağıdaki kod, tanımlanmamış davranışları (takma ihlalden dolayı veya başka bir nedenle) çağırıyor mu? a ve b aynı tür işaretçiler olabilir ve böylece takma birbirine izin çünkü düz int * yerine işaretçi-dizi tipleri kullanılarak karşılık gelen kod, mükemmel yasal olacağınıDizi işaretçisi takma adı - tanımsız davranış?

int foo(int (*a)[10], int (*b)[5]) 
{ 
    (*a)[5]++; 
    return (*b)[0]; 
} 

int x[10]; 
foo(&x, (int (*)[5])&x[5]); 

not edin.

Düzenleme: Bu aslında bir örtüşme ihlal edip ilginç sonucu, restrict anlambilimini öncesi C99 almak için hackish ama geçerli bir yol gibi görünüyor olmasıdır. olduğu gibi: Her adreste, gerçek bir dizi erişmek için gerekli Muhtemelen eğer

void some_func(int *aa, int *bb) 
{ 
    int (*a)[1] = (void *)aa; 
    int (*b)[2] = (void *)bb; 
    /* Now **a and **b can be assumed by the compiler not to alias */ 
} 

, sen farklı boyutları gibi SIZE_MAX-1 ve SIZE_MAX-2 vb kullanabilirsiniz.

+1

Aynı türden işaretçilerdir, takma adlara ait değiller. –

cevap

4

Burada farklı tipte işaretçiler aracılığıyla nesneleri erişen değildir: Eğer dizi nesneleri manipüle edilmez hangi a ve kendilerini ancak nesneler (*a)+5 ve (*b)+0, yani *((*a)+5) ve *((*b)+0) tarafından işaret b nokta. Bunlar aynı türden işaretçiler olduklarından, aynı nesneye iyi bir şekilde uyuşabilirler. (x yanında sadece bir kere değerlendirilmektedir) ve basit atama = için standart

diyor x = x + 1 için ++ eşdeğerdir:

++ operatör tarafından örtülü atama nesneye geçerli bir atama (*b)+0 tarafından işaret olduğunu Bir nesnede saklanan değer, herhangi bir şekilde birinci nesnenin depolanmasıyla üst üste binen başka bir nesneden okunduğunda, o zaman örtüşmesi tam olacaktır ve iki nesne, uyumlu bir t kalitesine sahip veya niteliksiz sürümlerine sahip olmalıdır. ype; aksi halde, davranış tanımsızdır.

Buradaki türler tam olarak aynıdır ve çakışma kesin.

+0

+1 Çok ilginç. Yine de, tüm bu işaretçilerden anlamsız şeylerden nefret ediyorum… –

+0

Bu mantıkla, 'int [5] [5]' erişemez ve bir overlaid [int] [25] 'de geçerli olur ...? –

+0

@R .. evet, geçerli olacağını düşünüyorum. Diziler bir şekilde gri bir bölgede. Bir 'struct' için 'toto.x' alanına erişmenin bir bütün olarak nesneye eriştiği açıktır, 'A [24] 've' B [4] [4] 'işaretçi aritmetiği ile tanımlanır ve böylece hiçbir zaman bir bütün olarak dizi. –