Portál AbcLinuxu, 14. května 2025 13:20

Dotaz: Řazení pointerů

15.12.2016 19:20 Franta
Řazení pointerů
Přečteno: 542×
Odpovědět | Admin
Vytvářím RB strom v C a chci položky porovnávat podle ukazatele (jedná se o "internované" řetězce, takže mi stačí porovnat ukazatel a né obsah). V C++ můžu použít std::less k porovnání takových ukazatelů (total ordering). Je nějaké makro či něco v C, co má stejnou garanci? Operátor < nelze k porovnání pointerů na různé objekty použít.
Nástroje: Začni sledovat (0) ?Zašle upozornění na váš email při vložení nového komentáře.

Odpovědi

15.12.2016 23:30 Michal Kubeček | skóre: 72 | Luštěnice
Rozbalit Rozbalit vše Re: Řazení pointerů
Odpovědět | | Sbalit | Link | Blokovat | Admin
Striktně podle normy ne, prakticky to můžete přetypovat na long unsigned (chcete-li být korektní, tak třeba uintptr_t a porovnávat ta čísla. Ale v každém případě je to hraní si s ohněm a moc bych to nedoporučoval.
17.12.2016 02:27 Andrej | skóre: 51 | blog: Republic of Mordor
Rozbalit Rozbalit vše Re: Řazení pointerů
Striktně podle normy ne,…
Dokonce je to undefined, což je ale podle mě spíš relikt z děsivých dob far/near pointerů než dnešní problém. (Far/near pointery nejsou v C standardu, ale jsou příkladem oné hypotetické situace, kdy porovnání pointerů nemusí dávat smysl.) Například clang přeloží tohle s -Weverything bez keců, což sice neříká absolutně nic o souladu s normou, ale možná to aspoň vzdáleně naznačuje, že porovnatelnost bude na této konkrétní platformě fungovat předvídatelně. (V klasickém lineárním virtuálním adresním prostoru se nic překvapivého vymyslet nedá.)
…prakticky to můžete přetypovat na long unsigned (chcete-li být korektní, tak třeba uintptr_t a porovnávat ta čísla. Ale v každém případě je to hraní si s ohněm a moc bych to nedoporučoval.

Já bych to castnul na const void*, což přímo v kódu dokumentuje, že se jedná o pointery a porovnání pointerů, a zakazuje (případnou) pointerovou aritmetiku.

16.12.2016 23:30 Ondřej Novák
Rozbalit Rozbalit vše Re: Řazení pointerů
Odpovědět | | Sbalit | Link | Blokovat | Admin
Můžete to zkusit všechno přetypovat na (char *) nebo radši (const char *) a pak to jde porovnávat.

Osobně bych doporučoval, když už ten RB strom píšete, aby to umělo definovat porovnávací callback (když v tom C nejsou šablony), aby ten strom se dal využit ještě k něčemu jinému :)
17.12.2016 01:57 Andrej | skóre: 51 | blog: Republic of Mordor
Rozbalit Rozbalit vše Re: Řazení pointerů

Úplně klidně to může být void*.

#include <stdio.h>
#include <stdlib.h>

struct blah { int zee[80]; };

int main() {
  struct blah *const sth = (struct blah *)malloc(sizeof(struct blah));
  if (!sth) return EXIT_FAILURE;
  struct blah *const oops = (struct blah *)malloc(sizeof(struct blah));
  if (!oops) { free(sth); return EXIT_FAILURE; }

  const void *const nonsense = (const void *)sth;
  const void *const bullcrap = (const void *)sth;
  const void *const bullshit = (const void *)oops;

  printf("%d %d\n", nonsense < bullcrap, nonsense < bullshit);
  printf("%d %d\n", nonsense == bullcrap, nonsense == bullshit);

  free(oops);
  free(sth);

  return EXIT_SUCCESS;
}
17.12.2016 02:30 Andrej | skóre: 51 | blog: Republic of Mordor
Rozbalit Rozbalit vše Re: Řazení pointerů

Aha, správně bych tam měl mít víc datových typů než jeden, aby o opravdu dokumentovalo ten příklad z dotazu. No, co už. :-P

17.12.2016 14:45 Jardík
Rozbalit Rozbalit vše Re: Řazení pointerů
Pokud tam dá callback, tak aby označil všechny funkce inline a modlil se, že mu to kompilátor inlinuje a zoptimalizuje. Výkonově na tom bude lépe, pokud to nechá parametrizovat nějakými makry.
20.12.2016 13:02 Ondřej Novák
Rozbalit Rozbalit vše Re: Řazení pointerů
Zlatý C++ :) (trolling)
Bedňa avatar 24.12.2016 00:12 Bedňa | skóre: 34 | blog: Žumpa | Horňany
Rozbalit Rozbalit vše Re: Řazení pointerů
Odpovědět | | Sbalit | Link | Blokovat | Admin
Asi by som pozrel Google a použil nejakú hotovú knižnicu.
KERNEL ULTRAS video channel >>>

Založit nové vláknoNahoru

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.