Jak rozplést krížové #include

Jak rozplést krížové #include
« kdy: 27. 10. 2015, 10:42:32 »
Stojím pred velikým projektem který je pretkán #include a v *.h souborech ono magické
#ifndef _SOUBOR_H_
#define _SOUBOR_H_
...
#endif

To ješte jde. Považuje se to za klasiku a dá se to vydržet i když jste purista. Problém ale začína delat krížové #include. Teda když se A.h odkazuje na B.h a to zase nazpátek na A.h. Jiste chyba v návrhu. Chci to rozplést a ptám se jestli na to máte nejaký nástroj který by vám ukázal co kam odkazuje a také jak deláte tenhle "refektoring" vy.

Díky za inspiraci. Jakoukoliv.



Re:Jak rozplést krížové #include
« Odpověď #2 kdy: 27. 10. 2015, 11:12:14 »
Stojím pred velikým projektem který je pretkán #include a v *.h souborech ono magické
#ifndef _SOUBOR_H_
#define _SOUBOR_H_
...
#endif

To ješte jde. Považuje se to za klasiku a dá se to vydržet i když jste purista.
...
?

Ivan

Re:Jak rozplést krížové #include
« Odpověď #3 kdy: 27. 10. 2015, 12:10:50 »
AFAIK Eclipse CDT umi zobrazit "include hierarchy".

dsfasdfasdf

Re:Jak rozplést krížové #include
« Odpověď #4 kdy: 27. 10. 2015, 13:23:10 »
ja bych se na to vysral, ifdefy to resi.


Sten

Re:Jak rozplést krížové #include
« Odpověď #5 kdy: 27. 10. 2015, 13:36:51 »
ja bych se na to vysral, ifdefy to resi.

Všechny moderní překladače také podporují #pragma once.

JSH

Re:Jak rozplést krížové #include
« Odpověď #6 kdy: 27. 10. 2015, 14:00:40 »
Všechny moderní překladače také podporují #pragma once.
Podporují, ale taky tam upozorňují že není možné zaručit aby to vždycky fungovalo. V příčetných situacích to fungovat bude, ale na nějakém šíleném "symlinkovém" pekle si to může vylámat zuby.

gamer

Re:Jak rozplést krížové #include
« Odpověď #7 kdy: 27. 10. 2015, 14:03:15 »
Podporují, ale taky tam upozorňují že není možné zaručit aby to vždycky fungovalo. V příčetných situacích to fungovat bude, ale na nějakém šíleném "symlinkovém" pekle si to může vylámat zuby.

pragma once je bezpečnejší, zuby si vylámeš spíš s ifdefy. Stačí mít
dir1/file.h
dir2/file.h
a v obou souborech ifdef __FILE__. pragma once bude fungovat i v tomhle případě.

Re:Jak rozplést krížové #include
« Odpověď #8 kdy: 27. 10. 2015, 14:16:11 »
ja bych se na to vysral, ifdefy to resi.

#ifdefy podle mne učí k nepořádku, jasne ukazují že nemám kód pod kontrolou. Bohužel se to stalo praxi tak že už to pokládame za správne.

aaa158

  • ***
  • 242
    • Zobrazit profil
    • E-mail
Re:Jak rozplést krížové #include
« Odpověď #9 kdy: 27. 10. 2015, 15:11:27 »
ja bych se na to vysral, ifdefy to resi.

#ifdefy podle mne učí k nepořádku, jasne ukazují že nemám kód pod kontrolou. Bohužel se to stalo praxi tak že už to pokládame za správne.

To zalezi od velkosti projektu a poctu vyvojarov. One-man-shop suhlasim, velky projekt vyvijany teamom / pripadne viac teamov, APIs atd. to uz nie je take iste.

Shin

Re:Jak rozplést krížové #include
« Odpověď #10 kdy: 27. 10. 2015, 15:39:54 »
Jak chceš psát bez ifdefů / pragma once ? Klasicky se všechny věci který potřebuješ píšou do includů - to vede k několika-násobnému "připojení kódu" a tím pádem jediným přidáním includu na začátek řetězce rozbiješ celou kompilaci, pokud je soubor už includovanej dál. OK, pragma once je lepší řešení, ale příjde mi že řešení pomocí ifdef je hodně rozšířený a výsledek je naprosto stejnej.

Tady jde asi o cyklickou závislost tříd/struktur, ne? Tedy třída /struktura A definovaná v A.h potřebuje B definovanout v B.h a naopak?

Pokud jde o C++ tak potom použíj forward deklaraci a nebo lepší návrh, vzor.

Re:Jak rozplést krížové #include
« Odpověď #11 kdy: 27. 10. 2015, 16:31:47 »
Pokud jde o C++ tak potom použíj forward deklaraci a nebo lepší návrh, vzor.

No práve. Jazyk C/C++ podporuje prax že niečo vysuniem do *.h to potom includnem do *.c/*.cpp. A ked prekladač hlási chybu ohraničím to celé:
#idndef
#define
#endif

Nie žeby som to nepoužíval, ale za tie roky mám z toho pocit bezmocnosti. V tej chvíli cítim že strácam konktrolu nad tým čo robím. Nakoniec to skončí u krížového #include a zúrivého skúšania kde je to nutné prehodiť aby to šlo skompilovať. :-\

pb.

Re:Jak rozplést krížové #include
« Odpověď #12 kdy: 27. 10. 2015, 19:04:27 »
No práve. Jazyk C/C++ podporuje prax že niečo vysuniem do *.h to potom includnem do *.c/*.cpp.

To "niečo" by měly být ideálně pouze deklarace a pokud chcete usnadnit překladači trošku času, pak forward deklarace.

A ked prekladač hlási chybu ohraničím to celé:
#idndef
#define
#endif
Tohle není chyba překladače nebo návrhového vzoru "include soubor v C". To je neukázněnost programátora. Dá se to vyřešit snadno - udělejte si pro svůj editor šablonky tak, aby se vám při vytváření nového hlavičkového souboru vždy otevřela potřebná šablona. Popis najdete například zde:

http://stackoverflow.com/questions/162617/how-can-i-automatically-add-some-skeleton-code-when-creating-a-new-file-with-vim

a do šablony si dejte například tohle:
Kód: [Vybrat]
/**
 * @file
 * @author Moje Jmeno <moje.adresa@moje.domena.cz>
 */
#ifndef __H_
#define __H_

/**
 * @brief
 */
class {
};

#endif

Zvyšíte tak své šance, že zvítězíte nad svou neukázněností a váš kód bude vypadat trochu lépe a překladatelněji, o problémy se vám automaticky postará překladač, a přestanete mít pocit, že nemáte kód pod kontrolou. Přestaňte řešit záležitosti, které umí snadno řešit technika.

Použití této šablony samozřejmě znamená, že se překonáte a doplníte do ifndef a define nějaký smysluplný název makra. Je možné, že existuje i lepší řešení, které přesvědčí editor, aby sem doplnil něco vhodného sám.

pb.

Re:Jak rozplést krížové #include
« Odpověď #13 kdy: 27. 10. 2015, 19:15:05 »
Ještě jsem se díval do odkazu předřečníka gamer, a i když jsem to už uvedl, zopakuji to a rozvedu:
  • Do hlavičkového souboru patří pouze deklarace
  • Bez problémů jsou v hlavičkových souborech inline funkce.
  • Pokud víte, co děláte a proč to děláte, můžete tam dát ještě makra.
Dáte-li do hlavičky nějaký kód nebo nedejK&R tělo nějaké funkce či proměnnou, nedostanete se přes linkování.

hu

Re:Jak rozplést krížové #include
« Odpověď #14 kdy: 27. 10. 2015, 20:15:46 »
Ještě jsem se díval do odkazu předřečníka gamer, a i když jsem to už uvedl, zopakuji to a rozvedu:
  • Do hlavičkového souboru patří pouze deklarace
  • Bez problémů jsou v hlavičkových souborech inline funkce.
  • Pokud víte, co děláte a proč to děláte, můžete tam dát ještě makra.
Dáte-li do hlavičky nějaký kód nebo nedejK&R tělo nějaké funkce či proměnnou, nedostanete se přes linkování.

Když už, tak do headerů deklarace pouze veřejné části rozhraní modulu, někteří experti tam cpou i věci, co měly zůstat se statickou deklarací uvnitř implementačního zdrojáku.