Gentoo Forums
Gentoo Forums
Gentoo Forums
Quick Search: in
[SOLVED][OT] Problemy z unią w C
View unanswered posts
View posts from last 24 hours
View posts from last 7 days

 
Reply to topic    Gentoo Forums Forum Index Polskie forum (Polish) Polish OTW
View previous topic :: View next topic  
Author Message
szolek
Guru
Guru


Joined: 30 Mar 2005
Posts: 570
Location: Brzóza Królewska

PostPosted: Wed Oct 04, 2006 8:27 pm    Post subject: [SOLVED][OT] Problemy z unią w C Reply with quote

Piszę program, w zasadzie na mały mikrokontroler i prześladuje mnie problem z stosowaniem unii. Unia wedle założenia umożliwia odwoływanie się do tego samego obszaru pamięci za pomocą różnych typów zmiennych. Więc w programie stosuje ją do zamiany 4 bajtów w jedną całą zmienną całkowitą.
Code:
 union {
   struct { char hi,mh,ml,lo;} b;
   long w;
}result;

czyli do poszczególnych bajtów odwołuje się przez zmienne:
Code:
result.b.hi
result.b.mh
result.b.ml
result.b.lo

a do całego słowa poprzez:
Code:
result.w

Problem jednak jest w tym że jak wpiszę do tej unii wartości bajt po bajcie to przy próbie odczytu mam stale zero.
Identycznie stosuje dla obszarów dwu-bajtowych i ten problem nie występuje.
Czy to wina kompilatora czy ja coś źle robię?

P.S.: Jeśli za bardzo OT to pogodzę się z wszelkimi konsekwencjami.
_________________
Zanim spróbujesz warto wiedzieć: to
Zapamiętaj tą stronę.
Nie zapominaj o tych radach.


Last edited by szolek on Wed Oct 04, 2006 9:47 pm; edited 1 time in total
Back to top
View user's profile Send private message
no4b
Bodhisattva
Bodhisattva


Joined: 18 Jan 2004
Posts: 774
Location: Tarnów, Poland

PostPosted: Wed Oct 04, 2006 8:56 pm    Post subject: Reply with quote

U mnie long ma 8 bajtów, może u Ciebie też, sprawdź.
_________________
GTK2/GNOME - The weakest link!
Back to top
View user's profile Send private message
13Homer
Guru
Guru


Joined: 12 Jul 2005
Posts: 461

PostPosted: Wed Oct 04, 2006 9:00 pm    Post subject: Reply with quote

Code:
#include <stdio.h>
int main() {
union {
   struct { char hi,mh,ml,lo;} b;
   long w;
}result;
result.b.hi=4;
result.b.mh=3;
result.b.ml=2;
result.b.lo=1;
printf("%d", result.w);
return 0;
}

wypisuje "16909060", więc u mnie najwyraźniej działa.
long ma u mnie 4 bajty (32-bitowy system), po usunięciu ml i lo wypisuje oczywiście inną liczbę (za każdym uruchomieniem inną), ale nie zero.
_________________
Lenovo ThinkPad R61 / C2D@2.6.24 / nVidia Quatro NVS 140M / 2 GB RAM
Back to top
View user's profile Send private message
szolek
Guru
Guru


Joined: 30 Mar 2005
Posts: 570
Location: Brzóza Królewska

PostPosted: Wed Oct 04, 2006 9:10 pm    Post subject: Reply with quote

char - 1B, int - 2B, long - 4B, float - 4B. double dla tych mikrokonwerterów np już nie istnieje.
_________________
Zanim spróbujesz warto wiedzieć: to
Zapamiętaj tą stronę.
Nie zapominaj o tych radach.
Back to top
View user's profile Send private message
argasek
Bodhisattva
Bodhisattva


Joined: 06 May 2004
Posts: 1120
Location: Sol [0,0], Poland, Kraków

PostPosted: Wed Oct 04, 2006 9:19 pm    Post subject: Reply with quote

Nie jestem pewien czy dobrze rozumiem, ale może być też tak, że deklarując w struct char a,b,c,d;, kompilator automatycznie podbija np. 1->4 bajtów w celu optymalizacji czasu dostępu do zmiennych. Miałem w każdym razie kiedyś taki problem i rozwiązałem go tak:
Code:

#if defined(__ELF__) && defined(__GNUC__)
#define __PS __attribute__((packed))
#else
#define __PS /* dummy */
#endif

struct {
    __PS char sig[17];
    __PS char name[20];
    __PS char whythis1a;
    // (...)
} head1;

itd.
_________________
RLU #137109 | BYKOM STOP! | Chcesz do mnie napisać? | jog
"Mam plany gotowe i wszystko, no i wiesz, idę do tego, no, mebloroba..." (Raaf) :D
Back to top
View user's profile Send private message
szolek
Guru
Guru


Joined: 30 Mar 2005
Posts: 570
Location: Brzóza Królewska

PostPosted: Wed Oct 04, 2006 9:46 pm    Post subject: Reply with quote

13Homer wrote:
Code:
#include <stdio.h>
int main() {
union {
   struct { char hi,mh,ml,lo;} b;
   long w;
}result;
result.b.hi=4;
result.b.mh=3;
result.b.ml=2;
result.b.lo=1;
printf("%d", result.w);
return 0;
}

wypisuje "16909060", więc u mnie najwyraźniej działa.
long ma u mnie 4 bajty (32-bitowy system), po usunięciu ml i lo wypisuje oczywiście inną liczbę (za każdym uruchomieniem inną), ale nie zero.

Kurcze nie pomyślałem żeby to sprawdzić na linuksowym gcc. I tu faktycznie wychodzi dobrze. W zasadzie odwrotna kolejność niż opisałem - hi jest najmniej znaczącym bajtem.

Program będę musiał dokończyć na tym kompilatorze.
_________________
Zanim spróbujesz warto wiedzieć: to
Zapamiętaj tą stronę.
Nie zapominaj o tych radach.
Back to top
View user's profile Send private message
Display posts from previous:   
Reply to topic    Gentoo Forums Forum Index Polskie forum (Polish) Polish OTW All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum