[ aleksazr @ 14.08.2016. 13:04 ] @
U okviru neke rutine imam deklarisanu varijablu v i odmah je inicijalizujem rutinom getINT():

int v = getINT();

getINT neće nikad vratiti nulu, kako to da kažem kompajleru, da varijabla v nije nula?

Mogu ovako, ali to generiše kod:
if (v == 0) return; // odavde pa nadalje, kompajler zna da je v != 0

Može nešto bez generisanja koda?
[ X Files @ 14.08.2016. 14:20 ] @
Ne znam tačno šta želiš da postigneš, ali svakako pogledaj i ASSERT:

http://www.cplusplus.com/reference/cassert/assert/
[ aleksazr @ 14.08.2016. 15:16 ] @
Odprilike znam šta radi ASSERT, ali to je C++.
Trebao sam napisati u tekstu da je C, a ne samo u subjectu.
Hvala u svakom slučaju.

Da uverim kompajler da je varijabla v != 0, kako on ne bi morao da testira.
Hteo sam da koristim FOR petlju, ali moraću DO-WHILE.
Nije da bi se dobilo nešto na brzini, ali ako ja već znam da ne može biti nula - zašto da testira.

[ Branimir Maksimovic @ 14.08.2016. 23:56 ] @
1. assert je C...
2. Kompajler nece generisati kod specificno za nulu...
[ Mihajlo Cvetanović @ 15.08.2016. 14:10 ] @
Kakvo je to neželjeno testiranje na nulu, koje kompajler radi? Misliš na for petlju? Najbolje je da je pretvoriš u do-while petlju, jer je tako očigledno šta želiš da postigneš. Programski kod ne služi samo kompajleru, nego i tebi, i ne samo sadašnjem tebi nego i budućem tebi, koji će zagarantovano zaboraviti neke detalje u vezi s kodom koje sada imaš u glavi. do-while petlja je najbolji način da kažeš i kompajleru i budućem tebi da ta petlja ne treba da testira uslov na početku petlje, nego na kraju.
[ negyxo @ 15.08.2016. 19:04 ] @
Za tako nesto najbolje da se prebacis u C++. Posto ces tamo moci prilicno lako da postavis constraint prosto dodavanjem nove definicije. Recimo mozes da definises klasu koja prima int ali koji je uvek veci od nula (to proveris u konstruktoru) pa zatim nadalje u programu koristis uvek tu klasu gde ti treba int > 0. To je sustina type systema, pride C++ ti omogucava da prosledjujes po referenci pa samim tim mozes biti skoro 100% siguran da klasa (tj. instanca koju budes prosledjivao) nece biti null (osim ako ne radis neke egzibicije sa castingom). Naravno ovo moze biti overkill za neke stvari, posto klasa ima veci overhead u odnosu na prost integer, ali to biras sam - performance vs safety :)
[ aleksazr @ 16.08.2016. 17:08 ] @
Da, mislio sam na for petlju... i prešao sam na do-while.

Nisam znao da assert ima i za C... ali, koliko znam, assert proverava run-time,
a to sam hteo da izbegnem. (napisao sam: Može nešto bez generisanja koda?)

A C++ bih radije izbegao :)
[ aleksazr @ 27.09.2021. 09:41 ] @
__assume(v != 0);

msdn
[ Nedeljko @ 30.09.2021. 20:49 ] @
Najbolje rešenje je ne reći to kompajleru nikako, već ubaciti runtime proveru

Code (c):

int v = getINT();

assert(v!=0);
// some code

Ubacivanjem informacije kompajleru se uvodi više problema nego što se rešava. Mala je to optimizacija, a problem koji se uvodi je što nema garancija da će taj uslov uvek biti zadovoljen.

Danas je to tako, ali projekat će se sutra menjati, pa če 0 postati moguća povratna vrednost funkcije, pa će programski kod koji sledi iza dodele vrednosti promenljivoj v postati nekorektan, jer ne obrađuje slučaj v==0 kako treba.

Ukoliko se ubaci assert, onda će se zaista trošiti neznatno vreme na runtime proveru, ali će u navedenom slučlaju prilikom runtime testiranja program da zvekne i napisaće koji je assert pukao, pa će se otići na to mesto i promeniće se programski kod tako da obrađuje navedeni slučaj kako treba.

Ovde se ubacivanjem __assume proizvodi više problema nego što se rešava. Dobija se neznatno na performanasama, ali od tih par ciklusa je važnije da se projekat završi do kraja, da radi korektno i da se može lako održavati. Ja sam uvek za optimizaciju i nerazbacivanje resursa, ali treba voditi računa i o prioritetima.
[ Burgos @ 02.10.2021. 22:31 ] @
Slažem se sa Nedeljkom. Herb Sutter je prošle godine napisao papir u kome opisuje iskustvo MSVC frontend-a i __assume:

http://www.open-std.org/jtc1/s...1/docs/papers/2020/p2064r0.pdf

Citat:
The only large-scale case I know of that did assume assertions was in the Microsoft C++ compiler front-end and
back-end. In summary: It arose unintentionally (the intent was the reverse, to assert assumptions), caused relia-
bility problems, and has been removed (with minor performance gains).


Citat:
Much to our surprise, the C1xx front end actually got a 1-2% faster with __assume statements
removed.


Strane 4, 5 i 6.
[ dragancesu @ 17.05.2023. 21:06 ] @
Da ne otvaram novu temu, program je školski, rezultat malo čudan

Code:
#include <iostream>

using namespace std;

int main()
{
    int a,b,c;
    cout<<a+b<<endl;
    cout<<"a "<<a<<endl;
    cout<<"b "<<b<<endl;
    cout<<"c "<<c;

    return 0;
}


kod nije dobar, nisu inicijalizovane varijable pa je rezultat malo čudan, recimo a+b daje 16

korišćen CodeBlock za ovo

pitanja su:
1. da li se može reći kompajleru da nedefinisane varijable inicijalizuje sa 0
2. ili treba neka opcija kompajlera da javi da varijabla nije definisana
[ djoka_l @ 17.05.2023. 22:11 ] @
1. ne
2. ne

Eventualno, static varijable su obicno postavljene na 0 i bez inicijalizacije. Ostale imaju slucajnu vrednost.
[ Mihajlo Cvetanović @ 19.05.2023. 15:48 ] @
Filozofija u C svetu je da kompajler ne radi ništa što mu ne kažeš. Nisi mu rekao da inicjalizuje promenljivu, pa je neće inicijalizovati. Ta inicijalizacija košta par nanosekundi, i ako će u nekom drugom delu koda promenljiva svejedno biti inicijalizovana na pravu željenu vrednost, onda je početna inicijalizacija bila uzaludno trošenje vremena. Par nanosekundi sami po sebi su skoro pa beznačajni, ali ako se taj kod izvršava 100000 puta u sekundi onda bi tih par nanosekundi pojelo bar 1% od ukupno potrošenog vremena. Ako praviš video igru ili neku kompleksni simulaciju onda su takve potrošnje značajne.

Zato ti kao početnik moraš ručno da inicijalizuješ sve što smatraš da bi trebalo automatski da se inicijalizuje. Možda nisi početnik, nego te samo mrzi. Svejedno, inicijalizacija mora da se navede da bi se izvršila.

Što se drugog pitanja tiče, u C jeziku omogućen ti je rad sa adresama na promenljive, pa kompajler ne može da bude dovoljno pametan da provali sve moguće načine na koje promenljiva može da bude inicijalizovana. Umesto da naprave kompajler koji radi polovičan posao proizvođači kompajlera uglavnom odluče da ne rade posao uopšte.
[ Nedeljko @ 30.05.2023. 06:54 ] @
Još nešto.

Ako treba napisati petlju koja se izvršava n puta, gde je n promenljiva koja može imati vrednost u opsegu od 5 do 105, onda petlju opet treba pisati tako da radi za sve vrednosti n u opsegu od 0 do INT_MAX. Na taj način se dobija kod koji je otporniji na probleme usled izmena tokom održavanja.
[ Ivan Dimkovic @ 30.05.2023. 07:24 ] @
U kontekstu C-a, jako je losa praksa oslanjati se na nekog drugog da inicijalizuje tvoje varijable, svakako ne nesto sto je podrazumeveno ponasanje kompajlera.

Najbolji nacin da se uvezbas je da u toku rada tvoj kod kompajliras u debug modu, sa -Wall (za gcc / Clang kompajlere) opcijom:

https://godbolt.org/z/xYc9sTWfq

Code:

<source>:8:11: warning: variable 'a' is uninitialized when used here [-Wuninitialized]
    cout<<a+b<<endl;
          ^
<source>:7:10: note: initialize the variable 'a' to silence this warning
    int a,b,c;
         ^
          = 0
<source>:8:13: warning: variable 'b' is uninitialized when used here [-Wuninitialized]
    cout<<a+b<<endl;
            ^
<source>:7:12: note: initialize the variable 'b' to silence this warning
    int a,b,c;
           ^
            = 0
<source>:11:17: warning: variable 'c' is uninitialized when used here [-Wuninitialized]
    cout<<"c "<<c;
                ^
<source>:7:14: note: initialize the variable 'c' to silence this warning
    int a,b,c;
             ^
              = 0
3 warnings generated.
Compiler returned: 0


Jos bolje je da dodas i -Werror (isto: gcc i CLang) koja kompajleru kaze da generise gresku umesto upozorenja i spreci te da koristis takav kod. Vrlo brzo ce ti uci u rutinu da pises korektan kod a to je izuzetno vazno zbog odrzavanja i sigurnosti. Na prvi pogled mozda smara, ali je zapravo jedina korektna stvar: kompajler cesto ne moze da zna sta ti tacno hoces da uradis, pa je daleko bolje ne ostavljati mogucnosti za interpretaciju.

Ako koristis MSVC, koristi /W4 (podesava nivo upozorenja) i /WX (tretira upozorenja ko greske).

Takodje, u pocetku ti jako moze koristiti da trcis dodatnu analizu koda, npr koristeci linter kao sto je Clang-Tidy. Visual Studio isto ima mogucnost da ti lintuje kod (MS to zove "Code Analysis"), tu ce ti biti ukazano na dodatne potencijalno opasne ili netacne stvari u kodu.