2016-03-16 19 views
6

union türünde dönen bir işlev var. Standart (C99) tarafından, değerden bir değişkene kopyalanmadan doğrudan çağrıdan döndürülen bir değere erişmesine izin verilir mi? İşte bir örnek ne demek istediğimi göstermek için:Döndürülmüş bir sendikanın bir değişkene değişken olmadan erişmesi yasal mıdır?

union thinga { int integ; char arr[4]; }; 

union thinga f(void) 
{ 
    union thinga t = {.integ = 1}; 
    return t; 
} 
int main(void) 
{ 
    printf("thinga is %d\n", f().integ); 
} 

alanda f().integ ile çağrı izin veriliyor mu? Benim örneğimde union ama sorun struct için aynı. Soruyu soruyorum, çünkü Solaris'in gcc 3.3'ünün bu yapıyı beğenmediğini ve cehennem gibi uyarılacağını hatırlıyorum. Problemi, struct ya da union alanlarına erişebilmek için dahili olarak görünmez bir değişken üretmek zorunda kalmasıydı. Yeni derleyiciler yapıya aldırış etmiyor gibi görünüyor ama ben bir gizli yakalama (yani düşünmedim undefined bevaviour olduğunu bilmek istiyorum.

DÜZENLEME yorumcu 2501 kapsamı nesnelerin dışarı işaretçi çürüyen diziye bağlantıları sağlayan tarafından fark, biz aynı durumdayız eğer biraz benim kodunu değiştirmek bakalım. verildiği şekilde

union thinga f(const char *val) 
{ 
    union thinga t = {.integ = 0}; 
    t.arr[0] = val[0]; 
    return t; 
} 

int main(void) 
{ 
    printf(" thinga.integ=%d .arr=%s\n", f("1").integ, f("1").arr); 
} 

bu durumda aynıdır arrays that are not lvalues and sequence point restriction ve Undefined behavior: when attempting to access the result of function call? (Döndürülen değer açıkça impementation bağlıdır (endiannes) ancak buradaki sorun bu değil.)

+0

Görünüşte işlev her zaman bir 'int' döndürüyor. Peki neden bir sendika kullanıyorsun? – Olaf

+2

'arr' üyesini kullanırsanız şaşırabilirsiniz: https://stackoverflow.com/questions/25759295/arrays-that-are-not-lvalues-and-sequence-point-restriction/25759612#25759612 Görünüşte ub C99: https://stackoverflow.com/questions/13755628/undefined-behavior-when-attempting-to-access-the-res-of-function-call/13755846#13755846 – 2501

+0

Sadece soru için var olan bir örnek. Gerçek projemde, sendika farklı modüller halinde farklı erişilen 3 farklı alana sahiptir. Örneği karmaşıklaştırmanın bir anlamı yoktur. –

cevap

3

Bu geçerlidir ve standart tarafından izin verilmiştir ve bu kodda tanımlanmamış bir davranış yoktur.

DÜZENLEME: pasajı

int main(void) 
{ 
    printf(" thinga.integ=%d .arr=%s\n", f("1").integ, f("1").arr); 
} 

f("1").arr için birliğin arr elemanı başvuruda bulunuyor. arr bir dizidir ve C kuralı gereğince, bu bağlamda dizinin ilk öğesinin işaretçisini bozar. t, işlev için yerel olduğundan (otomatik bir yerel değişken ve işlev geri dönüşünde artık mevcut olmayacaktır), arr öğelerine erişme, tanımlanmamış bir davranışı çağırır.

+1

Merak ediyorum: Linux platformunda güvenli mi? – LPs

+2

@LPs: Aradaki isimlendirilmiş değişkeni kullanmanın uzun yolu olarak güvenli bir iplik olmasını beklerdim. – Olaf

+0

@Olaf thx. Ben yapı ve sendikalar ortak bir alanda iade edildi eski bir derleyici/OS (introlne) ile ilgili sorunlar vardı çünkü bunu soruyordum. – LPs

0

Bu tabii ki, iyi tanımlanmış olduğu

printf("thinga is %d\n", (union thinga) {.integ = 1}.integ); 

, sadece aynıdır.

İlgili konular