C++ chybové hlásenia a kruhové závislosti

C++ chybové hlásenia a kruhové závislosti
« kdy: 21. 08. 2020, 10:34:45 »
Po pár mesiacoch som sa vrátil k C++ a UE4. UE má nad C++ vlastné nadstavby, takže je v tom radosť programovať. C++ ako jazyk ma baví, lebo sa v ňom dá stále objavovať nové zákutia a hlavne je to úplný opak hi-level jazykov ktorými sa živím.

No jedna vec čo mi na C++ compileroch prekáža sú veľmi neadresné chybové hlásenia, možno je to o skúsenostiach, ale C++ kompiler fakt programátora nevodí za ručičku (používam jak C-lang tak MSVC compiler).

Najhoršie odhalitelné chyby sú úplné kraviny, ktoré by sa dali vyriešiť za pár minút (keby bola lepšia chybová hláška) a často sa týkajú includovania súborov alebo namespacov. Včera som napríklad dlho nevedel prísť na to prečo sa mi nedá skompilovať projekt, až nakoniec som zistil, že sa niečo navzájom includuje (neviem či sa tomu nehovorí circular dependency). V iných platformách s kruhovými závislosťami nebol problém a ani ma nenapadlo, že si s tým compiler neporadí (viem že je to asi údel starších platforiem).

1. Ako sa takýto problém (kruhové závislosti) rieši v C++? Keď 2 triedy na seba odkazujú? Pomocou odkazovania na ich abstrakcie?, alebo sa to dá vyriešiť aj nejako priamočiarejšie?

2. Neexistuje nejaký nástroj ktorý by dokázal C++ kód rozanalyzovať tak že by mi poskytol lepšie chybové hlásenia?

PS: Dúfam že keď do C++ 20 prídu moduly, tak sa tieto problémy snáď konečne vyriešia.


Bugsa

Re:C++ chybové hlásenia a kruhové závislosti
« Odpověď #1 kdy: 21. 08. 2020, 10:50:48 »
V Arduino C to řeším tak, že si v souboru, který se bude includovat na více místech, definuji konstantu a pak kód zabalím do direktivy #ifndef. Nějak takto:

Kód: [Vybrat]
#define CONFIG
#ifndef CONFIG
....
můj kód
....
#endif

Re:C++ chybové hlásenia a kruhové závislosti
« Odpověď #2 kdy: 21. 08. 2020, 11:26:35 »
Pokud to jen trochu jde, tak je dobré se kruhovým závislostem vyhnout. Není to nic specifického pro C++.

Pokud je to opravdu nutné, tak se závislosti dají rozetnout přes forward deklarace :
Kód: [Vybrat]
// Foo.h :

struct Bar;
struct Foo {
  void Work( const Bar &bar );
};

// Foo.cpp :
#include "Foo.h"
#include "Bar.h"

void Foo::Work( const Bar &bar )
{
}

Princip je ten, že na pointer nebo referenci stačí o typu vědět, že existuje. Takže do headerů se nacpou forward deklarace a samotné includy přijdou až do .cpp. Pak je jedno, v jakém pořadí se Foo.h a Bar.h includují. Bar.h a Bar.cpp budou vypadat podobně.

Re:C++ chybové hlásenia a kruhové závislosti
« Odpověď #3 kdy: 21. 08. 2020, 13:05:58 »
pokud mas v hlavickach #ifdef _NECO_H_ a #define _NECO_H_ a #endif, pak je jedno kolikrat a kde hlavickovy soubor includujes, muzes klidne vsude, tak to zadne problemy delat pri kompilaci nemuze.
samozrejme neni rozumne to zasvinovat zbytecnyma hlavickama vsude.

Re:C++ chybové hlásenia a kruhové závislosti
« Odpověď #4 kdy: 21. 08. 2020, 15:54:19 »
@Bugsa:
Citace
Kód: [Vybrat]
#define CONFIG
#ifndef CONFIG
...
asi by měl být prohozen první a druhý řádek, ne?

@alex6bbc:
Citace
pokud mas v hlavickach #ifdef _NECO_H_ a #define _NECO_H_ a #endif ...
asi by mělo být
Kód: [Vybrat]
#ifndef _NECO_H ne?

Ač nestandardní, pro tenhle případ může být vhodné #pragma once, viz třeba https://en.wikipedia.org/wiki/Pragma_once


Re:C++ chybové hlásenia a kruhové závislosti
« Odpověď #5 kdy: 21. 08. 2020, 17:29:07 »
Ďakujem Vám všetkým za pripomienky. Prejdem si to a poskúšam.

Ja som všade použil ten (nenštandartný):
Kód: [Vybrat]
#pragma once ale aj napriek tomu som mal tento problém.

...

Aha takže deklarácia (bez definície). Toto asi pomôže.

Re:C++ chybové hlásenia a kruhové závislosti
« Odpověď #6 kdy: 21. 08. 2020, 17:34:24 »
Funguje to super! Ďakujem. Vlastne veď ja som tie forward deklarácie už videl v jednom screencaste (video tutoriale) ale vtedy autor toho videa nevysvetli, že načo to vlastne robí a až teraz mi to došlo.