Povečevanje pointerja v C

Vse o programiranju na in za PC

Moderatorji: Kroko, tilz0R

Povečevanje pointerja v C

OdgovorNapisal/-a Kroko » 02 Feb 2017, 22:41

Ali je s tem kaj narobe:

Koda: Izberi vse
*ptr++ = blabla(*ptr);

(ptr je uint32_t*)
http://www.planet-cnc.com poskakuješ na eni nogi in žvižgaš alpske podoknice Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 4773
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 680 krat
Prejel zahvalo: 1652 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: Povečevanje pointerja v C

OdgovorNapisal/-a zanka » 02 Feb 2017, 22:56

Meni to ne dela, čeprav je logično.
Uporabniški avatar
zanka
 
Prispevkov: 2569
Pridružen: 17 Mar 2016, 01:16
Zahvalil se je: 113 krat
Prejel zahvalo: 254 krat
Uporabnika povabil: DusanK
Število neizkoriščenih povabil: 50

Re: Povečevanje pointerja v C

OdgovorNapisal/-a Kroko » 02 Feb 2017, 23:05

Dela že, dela.
Ampak mogoče je boljše vprašanje - kaj točno tole naredi.
http://www.planet-cnc.com poskakuješ na eni nogi in žvižgaš alpske podoknice Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 4773
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 680 krat
Prejel zahvalo: 1652 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: Povečevanje pointerja v C

OdgovorNapisal/-a zanka » 02 Feb 2017, 23:17

Jaz sem sicer uporabil int, ampak mi ni delalo. :?
Koda: Izberi vse
int a;
int *b = &a;
*b = 4;
*b++ = 2 + *b;

b se je premaknil, ampak vsebina (b-1) je bila še vedno 4. Nisem pa pogledal koliko je a.

Enačaj najprej pogleda desno stran in jo priredi levi.
Velja: *b++ = *(b++). Ker sta plusa za b, se najprej priredi vrednost na polje, kamor kaže b, šele potem se poveča.
Uporabniški avatar
zanka
 
Prispevkov: 2569
Pridružen: 17 Mar 2016, 01:16
Zahvalil se je: 113 krat
Prejel zahvalo: 254 krat
Uporabnika povabil: DusanK
Število neizkoriščenih povabil: 50

Re: Povečevanje pointerja v C

OdgovorNapisal/-a tilz0R » 02 Feb 2017, 23:32

Stvar je jasna.

++ zadaj se izvede na koncu priredilnega bloka ali kateregakoli bloka.
++ spredaj se izvede najprej.
Knowledge sharing is people' caring., T. MAJERLE
Uporabniški avatar
tilz0R
 
Prispevkov: 1815
Pridružen: 18 Jan 2015, 00:12
Kraj: Črnomelj
Zahvalil se je: 229 krat
Prejel zahvalo: 509 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 255

Re: Povečevanje pointerja v C

OdgovorNapisal/-a Kroko » 02 Feb 2017, 23:39

Nisem prepričan, da je res tako jasno.

Koda: Izberi vse
uint32_t addone(uint32_t a)
{
  return a + 1;
}

uint32_t data[8] = { 111, 222, 333, 444, 555, 666, 777, 888 };

for (int i = 0; i < 8; i++)
{
  uint32_t* ptr = &data[0];
  for (int j = 0; j < 8; j++)
    {
      *ptr++ = addone(*ptr);
    }
 }

for (int i = 0; i < 8; i++)
{
  printf("%d = %d\n", i, data[i]);
}


Kaj vrne printf?
http://www.planet-cnc.com poskakuješ na eni nogi in žvižgaš alpske podoknice Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 4773
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 680 krat
Prejel zahvalo: 1652 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: Povečevanje pointerja v C

OdgovorNapisal/-a tilz0R » 02 Feb 2017, 23:44

Vsako vrednost povečano za 8 dobim, kar je za moje pojme popolnoma smiselno.
8x prišteješ 1 vsaki vrednosti.

Še vedno je zaenkrat zadeva jasna.

ptr++ se izvede po tem, ko se vrednost priredi *ptr.

Edit: Kot kaže stvar (spet) ni definirana v C-ju kako se izvede.
Sam se takega koncepta ne poslužujem. V takšnem primeru ptr++ izvedem posebej vrstico nižje in zagotovo vedno dela.
Priponke
Untitled.png
Untitled.png (4.92 KiB) Videno 957 krat
Knowledge sharing is people' caring., T. MAJERLE
Uporabniški avatar
tilz0R
 
Prispevkov: 1815
Pridružen: 18 Jan 2015, 00:12
Kraj: Črnomelj
Zahvalil se je: 229 krat
Prejel zahvalo: 509 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 255

Re: Povečevanje pointerja v C

OdgovorNapisal/-a zanka » 02 Feb 2017, 23:46

Svinjarijo
Koda: Izberi vse
0 = 223
1 = -5674441
2 = -5674442
3 = -5674443
4 = -5674444
5 = -5674445
6 = -5674446
7 = -5674447

gcc 5.1
Uporabniški avatar
zanka
 
Prispevkov: 2569
Pridružen: 17 Mar 2016, 01:16
Zahvalil se je: 113 krat
Prejel zahvalo: 254 krat
Uporabnika povabil: DusanK
Število neizkoriščenih povabil: 50

Re: Povečevanje pointerja v C

OdgovorNapisal/-a Kroko » 02 Feb 2017, 23:50

Če zadevo prevedem na Linuxu ne dobim takega rezultata.
Vsakič, ko zaženem aplikacijo dobim drugačen rezultat.
Nazadnje je bilo takole:
0 = 61001464
1 = 61001463
2 = 61001462
3 = 61001461
4 = 61001460
5 = 61001459
6 = 61001458
7 = 61001457

Malo prej pa takole:
0 = 56811240
1 = 56811239
2 = 56811238
3 = 56811237
4 = 56811236
5 = 56811235
6 = 56811234
7 = 56811233

Nekaj je narobe vendar ne vidim kaj.
http://www.planet-cnc.com poskakuješ na eni nogi in žvižgaš alpske podoknice Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 4773
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 680 krat
Prejel zahvalo: 1652 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: Povečevanje pointerja v C

OdgovorNapisal/-a Kroko » 02 Feb 2017, 23:53

Koda je iz enega kriptografskega algoritma in ni moja.
Sem kar nekaj časa iskal, kaj je narobe da mi na Linuxu ne dela prav.
Moram sedaj prepisati v nekaj boljšega.
http://www.planet-cnc.com poskakuješ na eni nogi in žvižgaš alpske podoknice Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 4773
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 680 krat
Prejel zahvalo: 1652 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: Povečevanje pointerja v C

OdgovorNapisal/-a tilz0R » 02 Feb 2017, 23:54

Kroko je napisal/-a:Moram sedaj prepisati v nekaj boljšega.


Samo ++ del daj v novo vrstico in dela :)
Knowledge sharing is people' caring., T. MAJERLE
Uporabniški avatar
tilz0R
 
Prispevkov: 1815
Pridružen: 18 Jan 2015, 00:12
Kraj: Črnomelj
Zahvalil se je: 229 krat
Prejel zahvalo: 509 krat
Uporabnika povabil: s56rga
Število neizkoriščenih povabil: 255

Re: Povečevanje pointerja v C

OdgovorNapisal/-a zanka » 02 Feb 2017, 23:55

Pretvori v dva koraka:
Koda: Izberi vse
*p = xxx;
p++;

Za prirejanje.
Uporabniški avatar
zanka
 
Prispevkov: 2569
Pridružen: 17 Mar 2016, 01:16
Zahvalil se je: 113 krat
Prejel zahvalo: 254 krat
Uporabnika povabil: DusanK
Število neizkoriščenih povabil: 50

Re: Povečevanje pointerja v C

OdgovorNapisal/-a Sigi » 03 Feb 2017, 00:15

V Gnusu, Mingw 32bit:

compiler zastoka:
..\src\AAA_file_test.c:62:7: warning: operation on 'ptr' may be undefined [-Wsequence-point]
*ptr++ = blabla(*ptr);
^

Koda: Izberi vse
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>


#define FLDLEN (8)
uint32_t *ptr;
uint32_t fld[FLDLEN] = {10,11,12,13,14,15,16,17};
char tempstr[128];

uint32_t blabla(uint32_t par) {
   par=par+ 5;
   return par;
}

int main(void) {
   ptr = fld;

   for(int i=0; i < FLDLEN; i++) {
      sprintf(tempstr,"pred: i=%d val=%d", i, fld[i]);
      puts(tempstr);
   }

   for(int i=0; i < FLDLEN; i++) {
      *ptr++ = blabla(*ptr);
   }

   for(int i=0; i < FLDLEN; i++) {
      sprintf(tempstr,"po: i=%d val=%d", i, fld[i]);
      puts(tempstr);
   }
   return EXIT_SUCCESS;
}



In izpiše:

Koda: Izberi vse
pred: i=0 val=10
pred: i=1 val=11
pred: i=2 val=12
pred: i=3 val=13
pred: i=4 val=14
pred: i=5 val=15
pred: i=6 val=16
pred: i=7 val=17
po: i=0 val=16
po: i=1 val=17
po: i=2 val=18
po: i=3 val=19
po: i=4 val=20
po: i=5 val=21
po: i=6 val=22
po: i=7 val=7



kar je malo mistično... :o

Če dam inkrement pointerja ločeno v novo vrsto, je rezultat ok:

Koda: Izberi vse
pred: i=0 val=10
pred: i=1 val=11
pred: i=2 val=12
pred: i=3 val=13
pred: i=4 val=14
pred: i=5 val=15
pred: i=6 val=16
pred: i=7 val=17
po: i=0 val=15
po: i=1 val=16
po: i=2 val=17
po: i=3 val=18
po: i=4 val=19
po: i=5 val=20
po: i=6 val=21
po: i=7 val=22


Sam nebi nikoli napisal takega stavka, je pa takle haklc fajn trening.

lp Žiga
lp Žiga
Sigi
 
Prispevkov: 237
Pridružen: 23 Jan 2015, 01:57
Kraj: Kamnik
Zahvalil se je: 116 krat
Prejel zahvalo: 82 krat
Uporabnika povabil: s54mtb
Število neizkoriščenih povabil: 19

Re: Povečevanje pointerja v C

OdgovorNapisal/-a Kroko » 03 Feb 2017, 00:28

Kako bi v Visual Studiu poiskal če še kje uporabljam vzorec *krneki++
http://www.planet-cnc.com poskakuješ na eni nogi in žvižgaš alpske podoknice Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 4773
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 680 krat
Prejel zahvalo: 1652 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: Povečevanje pointerja v C

OdgovorNapisal/-a S53DZ » 03 Feb 2017, 00:50

Po moje iščeš tole:
https://msdn.microsoft.com/en-us/library/2k3te2cs.aspx
Sicer pa išči po netu "visual studio search wildcard"
Uporabniški avatar
S53DZ
 
Prispevkov: 1164
Pridružen: 18 Jan 2015, 10:58
Kraj: Ljubljana
Zahvalil se je: 204 krat
Prejel zahvalo: 392 krat
Uporabnika povabil: S52O
Število neizkoriščenih povabil: 42

Re: Povečevanje pointerja v C

OdgovorNapisal/-a Sigi » 03 Feb 2017, 01:12

Kroko je napisal/-a:Kako bi v Visual Studiu poiskal če še kje uporabljam vzorec *krneki++


Sicer ti ne znam odgovorit, ampak samo kot pomislek, če bi iskal hroščke kot si ga opisal v tej temi, bi raje lovil warninge prevajalnika, ker *krenki++ je zelo popularen in legalen konstrukt.
lp Žiga
lp Žiga
Sigi
 
Prispevkov: 237
Pridružen: 23 Jan 2015, 01:57
Kraj: Kamnik
Zahvalil se je: 116 krat
Prejel zahvalo: 82 krat
Uporabnika povabil: s54mtb
Število neizkoriščenih povabil: 19

Re: Povečevanje pointerja v C

OdgovorNapisal/-a Kroko » 03 Feb 2017, 01:15

Najbrž res. Moram ugotoviti, kako se vklopi, da mi bo spodnja vrstica vrnila warning.
*ptr++ = blabla(*ptr);
http://www.planet-cnc.com poskakuješ na eni nogi in žvižgaš alpske podoknice Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 4773
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 680 krat
Prejel zahvalo: 1652 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: Povečevanje pointerja v C

OdgovorNapisal/-a gumby » 03 Feb 2017, 08:13

Samo vseeno... s tisto vrstico načeloma ni nič narobe, moralo bi delovati. Recimo tale primer:
Koda: Izberi vse
#include <stdio.h>
#include <stdint.h>

uint32_t addone(uint32_t a) {
   return a + 1;
}

int main(void) {

   uint32_t data[8] = { 111, 222, 333, 444, 555, 666, 777, 888 };

    for (int i = 0; i < 8; i++) {
      uint32_t* ptr = &data[0];
      for (int j = 0; j < 8; j++) {
         printf("i=%d j=%d ptr=%u d=%u -> ",i,j,ptr,*ptr);
         *ptr++ = addone(*ptr);
         printf("ptr=%u\n",ptr);
        }
    }

    for (int i = 0; i < 8; i++) {
      printf("%d = %d\n", i, data[i]);
    }
   
   return(0);
}


Izpiše se tole:
Koda: Izberi vse
i=0 j=0 ptr=2686608 d=111 -> ptr=2686612
i=0 j=1 ptr=2686612 d=222 -> ptr=2686616
i=0 j=2 ptr=2686616 d=333 -> ptr=2686620
i=0 j=3 ptr=2686620 d=444 -> ptr=2686624
i=0 j=4 ptr=2686624 d=555 -> ptr=2686628
i=0 j=5 ptr=2686628 d=666 -> ptr=2686632
i=0 j=6 ptr=2686632 d=777 -> ptr=2686636
i=0 j=7 ptr=2686636 d=888 -> ptr=2686640
i=1 j=0 ptr=2686608 d=223 -> ptr=2686612
i=1 j=1 ptr=2686612 d=334 -> ptr=2686616
i=1 j=2 ptr=2686616 d=445 -> ptr=2686620
i=1 j=3 ptr=2686620 d=556 -> ptr=2686624
i=1 j=4 ptr=2686624 d=667 -> ptr=2686628
i=1 j=5 ptr=2686628 d=778 -> ptr=2686632
i=1 j=6 ptr=2686632 d=889 -> ptr=2686636
i=1 j=7 ptr=2686636 d=4200529 -> ptr=2686640
i=2 j=0 ptr=2686608 d=335 -> ptr=2686612
i=2 j=1 ptr=2686612 d=446 -> ptr=2686616
i=2 j=2 ptr=2686616 d=557 -> ptr=2686620
i=2 j=3 ptr=2686620 d=668 -> ptr=2686624
i=2 j=4 ptr=2686624 d=779 -> ptr=2686628
i=2 j=5 ptr=2686628 d=890 -> ptr=2686632
i=2 j=6 ptr=2686632 d=4200530 -> ptr=2686636
i=2 j=7 ptr=2686636 d=4200529 -> ptr=2686640
i=3 j=0 ptr=2686608 d=447 -> ptr=2686612
i=3 j=1 ptr=2686612 d=558 -> ptr=2686616
i=3 j=2 ptr=2686616 d=669 -> ptr=2686620
i=3 j=3 ptr=2686620 d=780 -> ptr=2686624
i=3 j=4 ptr=2686624 d=891 -> ptr=2686628
i=3 j=5 ptr=2686628 d=4200531 -> ptr=2686632
i=3 j=6 ptr=2686632 d=4200530 -> ptr=2686636
i=3 j=7 ptr=2686636 d=4200529 -> ptr=2686640
i=4 j=0 ptr=2686608 d=559 -> ptr=2686612
i=4 j=1 ptr=2686612 d=670 -> ptr=2686616
i=4 j=2 ptr=2686616 d=781 -> ptr=2686620
i=4 j=3 ptr=2686620 d=892 -> ptr=2686624
i=4 j=4 ptr=2686624 d=4200532 -> ptr=2686628
i=4 j=5 ptr=2686628 d=4200531 -> ptr=2686632
i=4 j=6 ptr=2686632 d=4200530 -> ptr=2686636
i=4 j=7 ptr=2686636 d=4200529 -> ptr=2686640
i=5 j=0 ptr=2686608 d=671 -> ptr=2686612
i=5 j=1 ptr=2686612 d=782 -> ptr=2686616
i=5 j=2 ptr=2686616 d=893 -> ptr=2686620
i=5 j=3 ptr=2686620 d=4200533 -> ptr=2686624
i=5 j=4 ptr=2686624 d=4200532 -> ptr=2686628
i=5 j=5 ptr=2686628 d=4200531 -> ptr=2686632
i=5 j=6 ptr=2686632 d=4200530 -> ptr=2686636
i=5 j=7 ptr=2686636 d=4200529 -> ptr=2686640
i=6 j=0 ptr=2686608 d=783 -> ptr=2686612
i=6 j=1 ptr=2686612 d=894 -> ptr=2686616
i=6 j=2 ptr=2686616 d=4200534 -> ptr=2686620
i=6 j=3 ptr=2686620 d=4200533 -> ptr=2686624
i=6 j=4 ptr=2686624 d=4200532 -> ptr=2686628
i=6 j=5 ptr=2686628 d=4200531 -> ptr=2686632
i=6 j=6 ptr=2686632 d=4200530 -> ptr=2686636
i=6 j=7 ptr=2686636 d=4200529 -> ptr=2686640
i=7 j=0 ptr=2686608 d=895 -> ptr=2686612
i=7 j=1 ptr=2686612 d=4200535 -> ptr=2686616
i=7 j=2 ptr=2686616 d=4200534 -> ptr=2686620
i=7 j=3 ptr=2686620 d=4200533 -> ptr=2686624
i=7 j=4 ptr=2686624 d=4200532 -> ptr=2686628
i=7 j=5 ptr=2686628 d=4200531 -> ptr=2686632
i=7 j=6 ptr=2686632 d=4200530 -> ptr=2686636
i=7 j=7 ptr=2686636 d=4200529 -> ptr=2686640
0 = 4200536
1 = 4200535
2 = 4200534
3 = 4200533
4 = 4200532
5 = 4200531
6 = 4200530
7 = 4200529


Sam pointer je torej ok in kaže vedno na prave lokacije. Prvi WTF? se zgodi pri i=1 in j=0, kjer ptr sicer kaže na prvi (nulti) element tabele, prebere pa drugega. Namesto 112 prebere 223. To se potem ponavlja za vsak i in so na koncu vse vrednosti napačne.
Napaka je torej prisotna že pred vrstico "*ptr++ = addone(*ptr);"...
Optimizer se dela pametnega?
gcc (i686-posix-dwarf-rev1, Built by MinGW-W64 project) 6.2.0
my brain hurts
Uporabniški avatar
gumby
 
Prispevkov: 2573
Pridružen: 14 Jan 2015, 19:49
Kraj: Lendava
Zahvalil se je: 108 krat
Prejel zahvalo: 604 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 63

Re: Povečevanje pointerja v C

OdgovorNapisal/-a peterp » 03 Feb 2017, 10:17

Program od gumby-ja na Ubuntu 16.04.1 LTS x86_64, gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4)
Koda: Izberi vse
test.c:16:14: warning: operation on 'ptr' may be undefined [-Wsequence-point]
          *ptr++ = addone(*ptr);


Kot sem že zapisal pred časom v eni drugi temi: mi na pamet ne pride, da bi kaj takega sploh uporabljal. Tudi če je popolnoma veljavno je potrebno vedno na dolgo razmišljati, kaj zadeva sploh počne. Škoda časa.
peterp
 
Prispevkov: 657
Pridružen: 23 Feb 2015, 14:52
Kraj: Maribor
Zahvalil se je: 164 krat
Prejel zahvalo: 112 krat
Uporabnika povabil: gumby
Število neizkoriščenih povabil: 114

Re: Povečevanje pointerja v C

OdgovorNapisal/-a Kroko » 03 Feb 2017, 10:25

To sporno kodo so napisali v NXP in je del nekih NXP-jevih kriptografskih knjižnic.
Jaz sem samo zabil nekaj dni, ko sem iskal, zakaj pride do napake pri firmware posodobitvi v Linux verziji PlanetCNC TNG.

Priznam, da nisem imel vklopljenega -Wsequence-point.
http://www.planet-cnc.com poskakuješ na eni nogi in žvižgaš alpske podoknice Kroko was here!
Uporabniški avatar
Kroko
 
Prispevkov: 4773
Pridružen: 14 Jan 2015, 12:12
Kraj: Ljubljana
Zahvalil se je: 680 krat
Prejel zahvalo: 1652 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 255

Re: Povečevanje pointerja v C

OdgovorNapisal/-a MitjaN » 03 Feb 2017, 21:07

Kroko je napisal/-a:Ali je s tem kaj narobe:

Koda: Izberi vse
*ptr++ = blabla(*ptr);

(ptr je uint32_t*)


v principu se to zapiše kot
Koda: Izberi vse
*(ptr = ptr + 1) = blabla(*ptr);


tako imaš v enem ukazu dva enačaja. Kateri se bo izvedel najprej?
/sarkazem on
V tako dorečenem standardu kot je C so te seveda stvari definirane
/srakazem off
V realnosti pa je to še ena od nedifiniranih reči in je prepuščena prevajalniku.

Več o tem:
http://www.embedded.com/electronics-blogs/break-points/4394720/Sequence-points-
https://www.eskimo.com/~scs/readings/precvsooe.960725.html
MitjaN
 
Prispevkov: 88
Pridružen: 24 Feb 2015, 12:45
Zahvalil se je: 10 krat
Prejel zahvalo: 36 krat
Uporabnika povabil: aly
Število neizkoriščenih povabil: 7

Re: Povečevanje pointerja v C

OdgovorNapisal/-a gumby » 03 Feb 2017, 22:39

Torej v bistvu je potem fail vsak *x++, kjer x ni pointer na char?
my brain hurts
Uporabniški avatar
gumby
 
Prispevkov: 2573
Pridružen: 14 Jan 2015, 19:49
Kraj: Lendava
Zahvalil se je: 108 krat
Prejel zahvalo: 604 krat
Uporabnika povabil: Vrtni palček
Število neizkoriščenih povabil: 63

Re: Povečevanje pointerja v C

OdgovorNapisal/-a Sigi » 04 Feb 2017, 00:40

MitjaN je napisal/-a:
Kroko je napisal/-a:Ali je s tem kaj narobe:

Koda: Izberi vse
*ptr++ = blabla(*ptr);

(ptr je uint32_t*)


v principu se to zapiše kot
Koda: Izberi vse
*(ptr = ptr + 1) = blabla(*ptr);


tako imaš v enem ukazu dva enačaja. Kateri se bo izvedel najprej?
/sarkazem on
V tako dorečenem standardu kot je C so te seveda stvari definirane
/srakazem off
V realnosti pa je to še ena od nedifiniranih reči in je prepuščena prevajalniku.

Več o tem:
http://www.embedded.com/electronics-blogs/break-points/4394720/Sequence-points-
https://www.eskimo.com/~scs/readings/precvsooe.960725.html


Ne štekam; a nebi moral v principu zgornji izraz
Koda: Izberi vse
*ptr++ = blabla(*ptr);

(ptr je uint32_t*)[/quote]
razumeti kot
Koda: Izberi vse
*ptr = blabla(*ptr);
ptr++;


Izraz:
Koda: Izberi vse
*(++ptr) = blabla(*ptr);

pa bi napisal
Koda: Izberi vse
ptr++;
*ptr = blabla(*ptr);


A ni ravno to fora prefix in postfix operatorja?
Tu ne vidim dveh enačajev v izrazu.
lp Žiga
Sigi
 
Prispevkov: 237
Pridružen: 23 Jan 2015, 01:57
Kraj: Kamnik
Zahvalil se je: 116 krat
Prejel zahvalo: 82 krat
Uporabnika povabil: s54mtb
Število neizkoriščenih povabil: 19

Re: Povečevanje pointerja v C

OdgovorNapisal/-a Sigi » 04 Feb 2017, 01:39

Je pa zanimovo, da tole deluje:
*ptr = blabla(*ptr++);

Prevajalnik (Mingw 32) izpiše warning:

warning: operation on 'ptr' may be undefined [-Wsequence-point]
*ptr = blabla(*ptr++);
^

ampak rezultat je ok.

Ampak
lp Žiga
Sigi
 
Prispevkov: 237
Pridružen: 23 Jan 2015, 01:57
Kraj: Kamnik
Zahvalil se je: 116 krat
Prejel zahvalo: 82 krat
Uporabnika povabil: s54mtb
Število neizkoriščenih povabil: 19

Re: Povečevanje pointerja v C

OdgovorNapisal/-a Sigi » 04 Feb 2017, 02:18

Hmm, tole pojasni nekaj tega:

http://c-faq.com/expr/seqpoints.html

Na to sem naletel, ko sem iskal razlog zakaj mi tudi pri temle prevajalnik vrne isti warning:

Koda: Izberi vse
   int a=1;
   for(int i=0; i < 8; i++) {
      a = a++;
     printf("i=%d a=%d\n", i, a);
   }



in program izpiše:

i=0 a=1
i=1 a=1
i=2 a=1
i=3 a=1
i=4 a=1
i=5 a=1
i=6 a=1
i=7 a=1

Sam bom še naprej kodiral "na ziher", tole je le dodatna motivacija.
lp Žiga
Sigi
 
Prispevkov: 237
Pridružen: 23 Jan 2015, 01:57
Kraj: Kamnik
Zahvalil se je: 116 krat
Prejel zahvalo: 82 krat
Uporabnika povabil: s54mtb
Število neizkoriščenih povabil: 19

Re: Povečevanje pointerja v C

OdgovorNapisal/-a MitjaN » 04 Feb 2017, 09:40

prefix in postfix operator samo določa zaporedje kdaj se vrednost poveča glede na to kdaj se uporabi. Ne določa pa zaporedja glede na ostali izraz.

Prevajalnik lahko izraz
Koda: Izberi vse
*ptr++ = blabla(*ptr);


prevede kot:
Koda: Izberi vse
*ptr++;
*(ptr - 1) = blabla(*ptr);


ali kot:
Koda: Izberi vse
*(ptr) = blabla(*ptr);
*ptr++;


bistvena razlika je v tem, s katero vrednostjo *ptr je bila klicana funkcija.

Itak da samo čudno gledaš, ampak po C standardu ima prevajalnik proste roke. In prevajalniki danes sploh ob vklopljeni optimizaciji izkoristijo arhitekturo do konca. Tako da je lahko prva rešitev (kakorkoli nelogična se ti zdi) hitrejša za izvajanje bodisi zaradi cevovoda, cache-ja, hendlanja registrov ali katerega od drugih vplivov. In potem bo prevajalnik kodo izvedel pač na prvi način.

Zaradi tega te uporaba prefix in postfix operatorjev hitro lahko opeče po prstih. Določeni standardi zelo omejijo uporabo teh operatorjev (MISRA C 12.13)
MitjaN
 
Prispevkov: 88
Pridružen: 24 Feb 2015, 12:45
Zahvalil se je: 10 krat
Prejel zahvalo: 36 krat
Uporabnika povabil: aly
Število neizkoriščenih povabil: 7

Re: Povečevanje pointerja v C

OdgovorNapisal/-a Sigi » 04 Feb 2017, 10:55

No, no, tako na približno pa tudi ni. V linku ki sem ga prilepil dva posta nazaj je mehanizem lepo opisan. Dokler ne kršiš pravil je vse ok, ko pa greš preko je pa res rezultat nedefiniran, odvisen od razpoloženja prevajalnika.
lp Žiga
Sigi
 
Prispevkov: 237
Pridružen: 23 Jan 2015, 01:57
Kraj: Kamnik
Zahvalil se je: 116 krat
Prejel zahvalo: 82 krat
Uporabnika povabil: s54mtb
Število neizkoriščenih povabil: 19


Vrni se na Programski jeziki

Kdo je na strani

Po forumu brska: 0 registriranih uporabnikov in 1 gost