Melyik GCC standardot ajánljátok?

Fórumok

Sziasztok!

A napokban kénytelen voltam elővenni a C nyelvet, amihez nem sok pozitív élmény fűz (de ez legyen egy blogbejegyzés tartalma :) Leginkább JAVA háttérrel rendelkezem (amihez zömében pozitív élmények fűznek...).

Nem egy hatalmas projektről van szó, akár a default módban is kész lenne egykét nap alatt, de egy JAVA stílusú for ciklus rásakor kénytelen voltam felfigyelni a standardok opciójára a gccben. Csak lábjegyzetként a kód:
for (int i=0; i<VALAMI; i++) {

Nem akkora probléma a for előtt deklarálnom a ciklusváltozót (így a javából ismert működést produkálja szemben a fenti kóddal mondjuk Visual C-ben).

Az valódi kérdésem az, hogy nem igazán találtam vitákat a neten az egyes szabványok előnyéről hátrányáról, illetve melyik ami "hivatalosan" ajánlott új projektekhez. Amennyire láttam az alapértelmezett a gnu90 (standard C gnu kiterjesztésekkel). A c99 illetve gnu99 a másik esélyes versenyző és hogy olvastam a gnu1x a készülőben lévő új standard.

A portolhatóság nem elsődleges szempont, a kód a V4L-t használja, így nem cél, hogy mondjuk Visual C-ben leforduljon. Azt viszont szivesen venném, ha egyszer (a távoli jövőben) a V4L-t portolják BSD-re meg OS X-re ott (a majdnai GCC verzión) működjön.

Fontos lenne például, hogy jelenleg ez gond nélkül lefordul (még egy warning sem jön):
memset(buffer, max_length, ' ');
(A 2. és 3. paraméter meg van cserélve) - Ilyen szavashibák felfedezését elvárnám a fordítótól.

Szóval kíváncsi lennék a véleményekre prok és kontrák...

Hozzászólások

void * memset ( void * ptr, int value, size_t num );

Ez a memset deklarációja. Ha te fordító lennél, erre mit mondanál, amikor az int helyett (valószínűleg) int áll, a size_t (ami gondolom unsigned) helyett meg char? De az implicit konverziókra való warningolást nagyon szépen lehet bekapcsolni, gondolom te is megtaláltad ezt http://gcc.gnu.org/onlinedocs/gcc/Warning-Options.html
----
Hülye pelikán

Nem akarom, hogy hitvitába torkoljon a téma, de nem, nem olvastam el egy háború-és-béke méretű dokumentumot csupán a hibajelentésekről ;) Mindazonáltal -Wall bent volt.

Emellett ákeresve az "implicit conv" és "type conv" -ra sem találtam meg a megoldást. A -Wconversion is csak előjelre figyelmeztet, a többi téma pedig konstruktorokkal foglalkozik.

Amúgy melyik lenne a titkos kapcsoló ami megoldja?

És a fő témára visszatérve: neked melyik szabvány?

Szerintem - mivel a size_t valami typedef unsigned long lehet - semmi nem oldja meg azt a problémát, hogy a 0-ás karakter egyúttal unsigned int is, az pedig nem implicit konverzió C-ben, hogy unsigned longot csinálok belőle.

Ja, és a '' mindenképpen warningot generál -Wall-nál, mert üres karakter nincs a C-ben (error: empty character constant).

Ha rám hallgatsz - ha már C-t használsz -, a standard C-t használod, gnu extensionök nélkül. Minimum javasolt opció: -pedantic -Wall -Wextra

Tehát nincs //, mint komment, nincs for (int i = 0..., nincs blokk közepén változódeklaráció, stb.

Ezek nem olyan szintű kényelmi dolgok, amiket ne lehetne elkerülni, cserébe megtanulsz úgy kódolni, hogy később ne legyen belőle szopás, amikor valami véletlen folytán pl. egy másik compilert szeretnél használni, mert 10%-kal gyorsabb kódot generál az adott feladatra, és neked pont az a 10% fog még kelleni.

Szerintem.

A standardok elkötelezettje vagyok kézzel-lábbal, a // mint comment még megoldható valami regex-szel viszont a makrók sem tetszettek neki amit jelenlegi C hátteremmel elég nehezen tudnék debugolni. Ez egy természetétől fogva linux-alapú projekt, úgyhogy nem hiszem, hogy ennyire a C89 felé orientálódnék.

A más fordító kérdése viszont jó ötlet - erre a "performance" részére nem is gondoltam adolognak.

Azért ne higgy el mindent egyből, én a "mindent dekraláljunk előré"-t nem tartom jó dolognak. Lássuk az alábbi példát:

if(ritkanigazfeltetel){
/* ritkan lefuto programag */
int bazinagytomb[65535];
...
} else {
/* gyakran lefuto programag */
...
}

namost ha ez egy rekurzív függvény belsejében van, akkor pont hogy spórol a memóriával, míg a pedantic

int bazinagytomb[65535];
if(ritkanigazfeltetel){
/* ritkan lefuto programag */
...
} else {
/* gyakran lefuto programag */
...
}

kód nemkevés memóriát elpocsékol, ne adj isten még fel is zabálja, ami miatt kilövi az OS.

Szvsz: dekralájunk mindent a blokk elején. (mielőtt elkezdődne a flame, szvsz!)

Igazából az if utáni blokk is scopenyitó, tehát annak az elején is deklarálhatsz teljesen nyugodtan és (C89) szabványosan. Amikor C-vel kellett foglalkoznom, és pont hasonló volt a szituáció (nagy tömb kellett), akkor simán nyitottam egy blokkot a függvény közepén, mert a láthatósági/élettartam szabályok szépek és segítenek jobb kódot írni.

"Just a note: variables in ansi C don't have to be declared at the start of a function but rather at the start of a block."

Idézet innen.
----
Hülye pelikán

Azert az a 64K -s tomb a stack -en odab.sz!
Jo kis debuggolas lehet belole, hogy attol fuggoen honnan hivod neha megy, neha nem.
Masreszt jo nagy stack kell a proginak a ritkan lefuto kod miatt.

Jo, tudom, csak pelda volt, de azert jo ha megmarad az utokornak, hogy ilyet elvetemult dolog csinalni.

Nem akarok védeni senkit, de a C-nek több standardja is van, például 89-ben készült egy, amit a topik indítója is preferált. A legújabb nem mindig a legjobb.

Amúgy offtopik címen nem humoros, hogy C++ szabvány előbb volt mint C? Pedig mindkét nyelvet erősen a szükség szülte és erősen a gyakorlat befolyásolta, aztán mégis Bjarne úgy gondolta.
----
Hülye pelikán

Én C99-et használom, a normális fordítók már mind jól támogatják (az MSVC++ nekem nem számít annak, de amúgy sem kell programoznom Win alá hála az égnek). Emellé ha nagyon tiszta kódot szeretnél, akkor használd ezeket az opciókat (csinálj Makefile-t ha még nincs, abba mentsd el, aztán nem kell rá emlékezned):

-Wsystem-headers -Werror -Wall -Wno-format-y2k -W -Wno-unused-parameter -Wstrict-prototypes -Wmissing-prototypes -Wpointer-arith -Wreturn-type -Wcast-qual -Wwrite-strings -Wswitch -Wshadow -Wcast-align -Wunused-parameter -Wchar-subscripts -Winline -Wnested-externs -Wredundant-decls -Wno-pointer-sign

FreeBSD-n van egy WARNS make változó, amit 0-6-ig lehet beállítani, ezzel szabályozva a warningok szigorúságát, a legtisztább kódok (WARNS=6) ezekket az opciókkal fordulnak. És ott a -Werror is, hogy ha warning csúszna bele, akkor a programozó szépen javítsa csak ki.

ANSI módra:
gcc -ansi -pedantic -W -Wall -Wextra -Wconversion -Wshadow -Wpointer-arith -Wcast-qual -Wcast-align -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Wformat=2 -Wformat-security -fshort-enums -fno-common -O3 -ggdb

Ez elégséges infót dob ki, ha elqrnál vmit.
Illetve Beanie-ébe merge-eld bele :)
--
"SzAM-7 -es, tudjátok amivel a Mirage-okat szokták lelőni" - Robi.

Elvileg az enyim mindent implikál, ha jól tudom. AFAIK, a -pedantic meg csak valami kompozit kapcsoló, ami egyszerre több -W* kapcsolót is jelent. A -ggdb csak akkor, ha debuggolni akarsz, mert lassabb lesz a program és növeli a méretet. És épp emiatt értelmetlen a -O3 optimalizálással együtt használni, ahogy előttem is mondták.

"Nem egy hatalmas projektről van szó, akár a default módban is kész lenne egykét nap alatt, de egy JAVA stílusú for ciklus rásakor kénytelen voltam felfigyelni a standardok opciójára a gccben. Csak lábjegyzetként a kód:
for (int i=0; i?VALAMI; i++) {"

ez a C99 standard resze, minden c99 szabvanyt implementalo fordito tudni fogja (viszont visual studio nem ilyen). nem is kezdenek masban kodot, mint c99, ha nem muszaj.

c99-rol itt: http://www.kuro5hin.org/story/2001/2/23/194544/139

"ha egyszer (a távoli jövőben) a V4L-t portolják BSD-re meg OS X-re ott (a majdnai GCC verzión) működjön."

fyi evek ota van: http://netbsd.gw.com/cgi-bin/man-cgi?video++NetBSD-current
tovabba solarison es openbsd-n is.

--
NetBSD - Simplicity is prerequisite for reliability

"ez a C99 standard resze, minden c99 szabvanyt implementalo fordito tudni fogja (viszont visual studio nem ilyen)"

Most direkt kipróbáltam: Visual Studio 2005 (8.0) SP1 simán fordítja. Ez a fordító 5 éves. Felhívnám a figyelmet arra, hogy ( Visual Studio 6.0 != Visual Studio )! Tekintve, hogy azóta kint van 4 újabb verzió, elég csacsi hozzáállás ez. Nem mellékesen: akkor a gcc-t is egy régivel kell azonosítani (pl.: 2.0)?? Mert hát az sem leányálom...

Egyébként jelenleg nincs C99-es fordító a piacon tudtommal, csak az intel. FYI: GCC
MS hivatalos álláspont: Link

És akkor C++0x is:
GCC
VS C++ 2010
--
És hogy ontopic is legyek: Link - tehát a válasz: C89 vagy használj C++-t. :)
--
http://www.naszta.hu

Mivel én C++-ozom főleg, ritkán futok bele. :) Én mostanában már az open source-ot is VS alatt csinálom, mert kényelmes és CMake is támogatja. Normálisan dokumentálva van az STL is, és az IntelliSense is jól használható. Megmondom őszintén a nyilt IDE-kből mindig hiányzott valami apróság sajnos. Talán Qt Creator 2-3 verzió múlva... :)
--
http://www.naszta.hu


   for(int i=0; ...

Nincs ezzel semmi baj, a VC Toolkit 2003 is jól fordítja.

A paraméterek felcseréléséről. A compiler természetesen nem tud minden hibát kiszűrni, ezért ne akard megspórolni a program tesztelését. A tesztelés _minimuma_, hogy minden programsor végrehajtását ellenőrzöd, akkor pedig az ilyen hiba kiderül.

--
CCC3

Arra utalok, hogy itthon a tesztelése a kódnak nem elsődleges szempont. Ahogy látom a te fejedben ez úgy él, hogy neked kiadják, mit csinálj, és te akkor adod át, amikor akarod. Ez még akkor sem így megy, ha saját céged van és saját saját saját, hát még ha alkalmazottként vagy.
----
Hülye pelikán

Szerintem nem tudtad kovetni. Epphogy nem, mert normalis helyen tenyleg vegigtesztelik a program minden egyes sorat, csak normalis helyen ez benne van a hataridoben, mert a projvez a teszteles idejet is bekalkulalja, ami itthon nem divat valamiert.
--


()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

Itt két külön dologról van szó, de nem tudtok elvonatkoztatni.
Mrev azért volt naív az én szememben, mert valahogy sütött róla, hogy szerinte a program akkor van kész, amikor ő úgy gondolja, hogy készen van.
Az is a naivitás, hogy valaki azt feltételezi, Mo-n a normális, alapos tesztelés bevett szokás.
----
Hülye pelikán

En irtam is, hogy ez nalunk valahogy nem divat. Meg nalunk valahogy eleg sok minden nem divat, ami pedig fontos lenne... ezert van ennyi szar program, es valahogy kezdem erteni, hogy az allami megrendelesre keszulo szoftverek mitol olyan pocsek minoseguek, lasd abev.
--


()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

A C99 GCC 4.5.0-tel lassabb lehet nagy számolásigény esetén:

On x86 targets, code containing floating-point calculations may run significantly slower when compiled with GCC 4.5 in strict C99 conformance mode than they did with earlier GCC versions. This is due to stricter standard conformance of the compiler and can be avoided by using the option -fexcess-precision=fast; also see below.

Ha olyan alkalmazást szeretnék írni C-ben ami fut winen és unixon (ural2) is ahhoz mit ajánlanátok?

Root-Tech

Ezt messzemenőkig tudom támogatni (mindkettő részt, de főleg az utóbbit), a C++ tele van dolgokkal, amelyek egy része átment a C nyelvbe mint kiegészítés, egy kis része még a szabványba is került, de fontos dolgok hiányoznak még mindig. Gondolok itt például a tipusosságra.
----
Hülye pelikán