Rozdíl v deklaraci proměnné

Wiring, C++, C, Java, ...
Pravidla fóra
Toto subfórum slouží k řešení obecných otázek kolem programování (konstrukce, knihovny, alokace paměti, ...)
Odpovědět
PetrB
Příspěvky: 81
Registrován: 20 čer 2018, 13:39
Reputation: 0

Rozdíl v deklaraci proměnné

Příspěvek od PetrB » 06 dub 2021, 18:22

Ahoj,
narazil jsem na zvláštní problém.
měl jsem tento kód

Kód: Vybrat vše

 switch (volba) {
        case -2:
		...
		break;
	case 0:
	        ...
		break;
	case 1:
	        ...
		break;
	case 2:   
		int b0;  //Tady
		b0=digitalRead(ID());		
		break;
	case 3:
		Serial.print(F("Volba="));
		Serial.println(volba);
		break;
	}

v části //Tady jsem měl zapsáno

Kód: Vybrat vše

 int b0=digitalRead(ID());
a v tom případě nikdy k větvi 3 nedošlo. I když volba byla rovna 3

Ve chvíli, kdy jsem to napsal, jak je to teď

Kód: Vybrat vše

          int b0;  //Tady
	  b0=digitalRead(ID());	
Tak to funguje a větev 3 prochází.

Nevíte, k čemu mohlo dojít? Jaký je rozdíl pro překladač? Myslel jsem, že to je totožné, ale podle chování programu ne.

Díky

ondraN
Příspěvky: 601
Registrován: 08 srp 2019, 20:01
Reputation: 1

Re: Rozdíl v deklaraci proměnné

Příspěvek od ondraN » 06 dub 2021, 19:29

Je to prosté. V C ani C++ není povolená podmínečná deklarace v příkazu podmínky, tedy ani v příkazu switch. Určítě ti to psal i kompilátor, takže je dobré si v IDE povolit, aby zobrazovalo všechny výstrahy kompilátoru. Správně by to nemělo fungovat ani teď, ale možná to kompilátor sám definoval ještě před tou podmínkou. Pokud se i za příkazem switch dostaneš k té proměnné, tak byla definována ještě před ním, protože platnost proměnné je omezená na blok, kde je definovaná.

PetrB
Příspěvky: 81
Registrován: 20 čer 2018, 13:39
Reputation: 0

Re: Rozdíl v deklaraci proměnné

Příspěvek od PetrB » 06 dub 2021, 23:24

Díky za typ. Kompilátor mi píše různá info, že nemám inicializované místní proměnné, ale o tomto mi nic neříká a zatím jsem nenašel, kde to nastavit (Visual studio).
Každopádně to vyzkouším.
Díky

ondraN
Příspěvky: 601
Registrován: 08 srp 2019, 20:01
Reputation: 1

Re: Rozdíl v deklaraci proměnné

Příspěvek od ondraN » 07 dub 2021, 06:57

Jak jsem zjištoval, tak některé překladače v případě, že je možné tu definici přesunout, to udělají automaticky. K problému dojde, pokud není definice samostatná (tvůj první způsob) nebo když je vně podmínky definovaná proměnná stejného jména.
Dobrou pomůckou pro správné definice je to, že si uvědomím, že místo v paměti pro každou proměnnou se musí alokovat v okamžiku překladu. A podmínka se vyhodnocuje až za běhu.
Pokud bych chtěl něco alokovat podmíněně, musí se pak použít dynamická alokace.

Uživatelský avatar
gilhad
Příspěvky: 576
Registrován: 07 bře 2018, 11:22
Reputation: 5

Re: Rozdíl v deklaraci proměnné

Příspěvek od gilhad » 07 dub 2021, 07:56

... Nebo to musi byt alokovane v bloku ktery je cely uvnitr podminky, a s koncem toho bloku to zase prestast existovat. (podobne jako je to s funkcema a jinyma blokama)

(Jo a taky v pripade nedefinovaneho chovani si muze kompilator delat co chce, treba tahat demony z nosu, nebo alokovat promenne kdekoli jinde, nebo havarovat dle libosti, nebo se libovolnym zpusobem vzpamatovat ... http://catb.org/jargon/html/N/nasal-demons.html )

ondraN
Příspěvky: 601
Registrován: 08 srp 2019, 20:01
Reputation: 1

Re: Rozdíl v deklaraci proměnné

Příspěvek od ondraN » 07 dub 2021, 09:35

Z toho je vidět, že některé "výhody" v C++, jako třeba možnost definice a deklarace téměř kdekoli, zase není až taková výhoda :mrgreen: V C je dané, že se proměnné definují a deklarují na začátku bloku. Pak nevznikají takové blbě hledatelné chyby. Snažím se tohle pravidlo dodržovat obecně. Jedinou vyjímku si dovoluji v případě definice jednorázové proměnné v cyklu for.
O víkendu jsem pomáhal synovi hledat chybku v programu v pythonu. To je teprve hrůza :twisted:

PetrB
Příspěvky: 81
Registrován: 20 čer 2018, 13:39
Reputation: 0

Re: Rozdíl v deklaraci proměnné

Příspěvek od PetrB » 07 dub 2021, 14:33

Chování bylo opravdu zvláštní. Zvládlo to vykonat (a to ještě ne vždy) max jednu instrukci ve větvi za touhle "trojkou". Ovšem zajímavé je, že na jiných místech mi obdobná konstrukce fungovala.
Každopádně se tomu pokusím vyhnout. Což by snad neměl být takový problém, protože také beru jako přirozenou deklaraci na začátku rutiny a ne až v jejím těle (jsem zvyklý z Pascalu/Delphi, ale tam už to také proniká) - zde jsem si chtěl vyzkoušet jiný přístup a zjevně jsem narazil ;-)

Odpovědět

Kdo je online

Uživatelé prohlížející si toto fórum: Žádní registrovaní uživatelé a 4 hosti