no nevím, je asi jasný, že vyhledávat "programování" a "programming" asi dá jiné výsledky, ne?
kromě XML/HTML tagů se <> používá kde třeba? mě napadla tedy spousta jiných věcí: https://en.wikipedia.org/wiki/Bracket#Angle_brackets
Vazne?? Clovek, kterej ma v popisku, ze pouziva Linux od roku 1994, nezna zakladni pravidla linuxovy dokumentace?
http://superuser.com/questions/134166/how-to-read-unix-usage
Koukám že oblíbenost asembleru raketově roste. Že by nový boom?
Fascinují mně takovéhle hloupé "indexy oblíbenosti" podle toho kolikrát je do vyhledávače zadaná nějaká 1 konkrétní fráze. Jakou to asi tam má vypovídací hodnotu, kromě toho že tolikrát prostě tu frázi lidé do vyhledávače zadali.
To bych netvrdil. V době vzniku C existovala hromada jiných jazyků a spousta z nich byla oproti C opravdu vysokoúrovňová. C byl od začátku navrhován jako vysokoúrovňový přenositelný Assembler s jednoduchým kompilátorem, algolskou syntaxí a bez vestavěných funkcí, které by nějak mohly být vázány na konkrétní OS, ale za to s modifikátory jako auto, register, intenzivním využíváním ukazatelů apod. - tedy jako nižší jazyk.
Třeba knihovny, úpravy existujících projektů,...
Co by se hodilo nejvíc, tak
- přetěžování funkcí, protože pamatovat si několik názvů je na pytel
- možnost vynutit silnější typovou kontrolu (souvisí s přetěžováním funkcí), implicitní přetypování na int je někdy pěkně otravný.
- namespace, protože PREFIX_funkce() je pěkně otravný a zapouzdřením do struktur program bobtná a leniví
- výjimky, protože http://www.cplusplus.com/reference/csetjmp/ je pěkně otravný a nefunguje na 100%
- bitový enumy (nepočítaly by 0, 1, 2, 3,.. ale 1, 2, 4, 8,... bez toho, že bych tam musel dopisovat hodnoty ručně)
- jasně definovaný pořadí bitů u bitově definované struktury, protože teď je použití třeba u hardwarovýho registru je nemožný
- Pole prvků menších než 1B (například u komunikačních protokolů, kde je třeba 10 stejných prvků velikosti 4b v poli 8B)
- jednoduchá možnost inicializace jenom některých položek ve struktuře (protože se jinak prasí RAMka, nebo se to blbě udržuje, nebo nelogicky přes .entity)
- dědičnost struktur, unií a enumů, protože jinak je to opruz a člověk se nevyhne hackování a chybám během údržby, balení struktur do struktur,...
- extern omezit jenom na const
- nějaká obdoba "with" z Pascalu, zvýší to přehlednost a ubere psaní -> vyšší produktivita, kompilátor ví, že si má hodit pointer do registru a nemusí se o něho starat (pokud není volatile)
- množiny z Pascalu by taky nebyly od věci, mohlo by to zpřehlednit flagy a ušetřit maskování bitů
- ...
Je to tak. Enum se interně v kompilátoru implementuje takto:
counter = 0;
while(unassignedItem) {
item=getUnassignedItem();
if(item.hasExplicitValue) {
counter = item.ExplicitValue;
}
assignValue(item, counter++);
}
Vyzkoušeno v IAR i v GCC, obojí naAVR, ARM7, ARM9, ARM11, CortexM* a MSP430
Na enumu od 0 není nic špatnýho. Pokračování od hodnoty tam je tam je (dle K&R), pokračuje se za poslední explicitní hodnotou. Mě šlo spíš o modelovou situaci:
Mám nějakou komunikaci. První vrstva je PHY+MAC, tam mám nějaký chyby (timeout,... ) a dám je do enumu. Přidám další vrstvu, řekněme šifrování. Najednou mám další chyby (invalid key,...) a potřebuju ten seznam chyb rozšířit o další hodnoty. Možnosti, co mám:
1) Nový enum s dalšíma chybama, začít poslední hodnotou z PHY+MAC. Jako výsledek nad šifrovací vrstvou použít jeden z těch dvou (jde to díky explicitní konverzi na in), ale při ladění vidím pro polovinu chyb jenom nic neříkající číslo.
2) Nový enum, kam přepíšu původní hodnoty a přidám další. Pokud potřebuju vložit další vrstvu mezi, nebo přidat třeba chybu parity, se kterou se nepočítalo, tak musím upravovat na víc místech, ale při ladění vidím výsledek a můžu menší přetypovat na větší (při zachování pořadí). Pokud mám pět enumů navázaných na nějaký s 200 položkama, je to na pos...
3) Lepičská metoda definování hodnot jako maker (sorry, nechci být za hňupa).
4) Definovat všechny kódy chyb v jednom enumu v extra hlavičce a skousnout, že všichni mají tušení o všech chybách.
5) To, co navrhuju:
enum L2Error {
enum L1Error,
ERR_INVALID_KEY,
...
}
Jenomže nejelegentnější řešení nemá kompilátor vůbec rád... :(
Toto moc nepomůže, protože je to ekvivalentní bodu 4 - všichni budou mít tušení o všech chybách, protože předchozí enum bude definovaný v hlavičkovém souboru, který budeš includovat ...
V podobných případech někdy používám metodu 3) ale definuji pro to extra datový typ (prostě přetypovávám čísla v #define na ten typ) na mnou vytvořený typ, takže vím, k čemu to patří - hodí se to pro flagy, pokud jich může být nastaveno více. Jestli někoho napadne něco lepšího rád se přiučím, protože to rozhodně není ideální. Nenašel jsem ideální způsob :-(
Nic ve zlém, ale to, co popisuješ, je právě celkově nesprávný návrh a z toho už plynou problémy, s nimiž se musíš vypořádat a můžeš si maximálně vybrat, zda-li nešikovně nebo ještě nešikovněji.
Každá vrstva produkuje vlastní chyby a vrstva vyšší má ošetřit chyby vrstvy nižší. V případě, že chybu nižší vrstvy nelze transparentně ošetřit, je nutné tuto chybu prezentovat nadřazené vrstvě, ovšem vhodně reinterpretovanou jako chybu vrstvy, jež se s ní jakožto prozatím nejvyšší nedokázala vypořádat. Z logiky vrstvené architektury plyne i logika šíření chyby: tak, jako vyšší vrstva představuje vyšší úroveň abstrakce, měla by i generovaná chyba odpovídat této vyšší úrovni abstrakce. Vyšší vrstva nemá funkčně přeskakovat vrstvu o úroveň níž, protože ta by pro ni měla představovat černou skříňku. A protože to jsou černé skříňky, tak vrstva objednu výš nezná její rozhraní a tedy ani nerozumí jejím chybám.
Další pojetí je hybridní, tedy že každá vyšší vrstva nemusí nutně komunikovat jen s vrstvou bezprostředně ležící níže, ale může komunikovat s kteroukoli vrstvou ležící níže. Pak ovšem musí rozlišovat i množiny chyb podle vrstvy s níž komunikuje a pro prezentaci chyby, kterou se jí nepodařilo ošetřit, platí to samé, co výše: reinterpretovat jako chybu vrstvy, která ji jako poslední zachytila.
Jakékoli jiné řešení šíření chyby už má smysl jedině informativní, pro účely logování či ladění; chyba vrstvy volané nepřímo skrze vrstvu ležící v hierarchii výše z logiky věcí nemá být ošetřována vrstvou, jež s ní přímo nekomunikovala.
A protože logovací/informativní funkce chyby je naprosto odlišná od její statusové funkce, mělo by se to řešit i samostatným logovacím modulem/vrstvou, s nímž budou jednotlivé moduly komunikovat přímo a který se už postará o vhodnou prezentaci posloupnosti objevivších se problémů a jejich lokalizaci tomu modulu, který o to bude mít zájem.
Aj aj! Jen doufám, že nikoho nenapadne do C něco podobného v budoucnu matlat.
- přetěžování: v žádném případě! I v jazycích, které to umožňují, je to častý zdroj záludných chyb, na což reagují standardy jako MISRA apod. a přetěžování omezují nebo zakazují používat zcela. Nicméně kdo bez toho nemůže žít, může použít C++.
- silnější typová kontrola: implicitně na to dnes kompilátory reagují varováním, obvykle je možné vynutit i vyšší úroveň varování či použít nástroje typu lint; v tom dnes žádný problém nevidím a opět zde platí, že je možné použít C++, jež má typovou kontrolu přeci jen silnější
- to je tvůj názor, např. já jsem na prefixy zvyklý - pokud to je vůbec kdy nutné; co nechci zveřejňovat, to udělám jako static, rozhraní modulu mohu opatřit prefixem, pokud je to nezbytné. Zavádět namespace jen kvůli tomu, že se mi nelíbí MP_procName() a chci místo toho psát MP::procName() mi připadá jako zbytečnost. Navíc už vidím, jak lidi sypou do namespace i lokální objekty, aniž by jejich lokálnost explicitně zaručovali... Ne, děkuji. Kdo bez toho nemůže žít, viz výše - C++.
- výjimky: Ne! Tohle by bylo na mnohem delší debatu a vysvětlování a asi i flame, ale výjimky jsou ve skutečnosti velmi kontroverzní konstrukce, které dělají z chyby nějaký speciální stav, což není. Navíc z podstaty věci dělají program lenivější, protože se implicitně kontrola udělat musí, i když to není nutné (např. je-li chyba ošetřena ve spodních vrstvách a vyšší se již mohou spolehnout na bezchybnost) - a je to mnohem, mnohem větší zátěž pro rychlost programu, než nepřímý skok, ke kterému by vedlo volání funkcí umístěných do struktur, na které si stěžuješ hned v prvním bodě. V jazyku úrovně C nemají výjimky co dělat! Řešení pro ty, kdo bez toho nemohou žít, v pořadí od nejpřijatelnějšího k nejhoršímu: 1. goto, 2. setjmp, 3. C++
- enum, další z konstrukcí, jejíž smysl je často nesprávně chápán, aneb "problém #define x enum x const int". Výčtový typ je určen k tomu, co napovídá jeho název: k výčtu pro vnitřní potřeby programu. Už použití rovnítka v enumu je nečisté a může být velmi nepřehledné, či nebezpečné (skákání tam a zpátky v rozsazích, do většího enumu stačí přidat hodnotu navíc a zbytek za tím se posune až před první další přiřazení...). Přiřazení by se v enumu vůbec nemělo vyskytovat a když, tak jen u první hodnoty, v dobře a bezpečně navrženém programu by na konkrétní hodnotě výčtových konstant nemělo vůbec záležet. Enum skákající implicitně po mocninách dvou - to už je prasečina na kvadrát, a to doslova. Od toho je #define.
- bitové pole je ze své podstaty nepřenositelná konstrukce, ačkoli uznávám, že by to bylo velmi příjemné; v embedded oblasti to nebývá problém, protože potřebuje-li někdo operovat na této úrovni, pak je velmi silně navázán na konkrétní platformu a na konkrétní překladač a u toho je již takováto věc definována
- pole prvků pod bajt: viz výše, ze své podstaty nepřenositelné a potenciální nesnáz při nedělitelnosti bajtu velikostí položky pole
- částečná inicializace struktur: tady také nevidím důvod, proč to neumožnit; potřeba něčeho takového sice na 90% indikuje bad coding practices, ale to není důvod to zakazovat
- extenze struktur ve stylu Oberonu: za 23 let, co programuji v C, mi to sice nijak zásadně nechybělo, ale myslím, že by to nebyla špatná vlastnost; ovšem i zde by se dalo napsat UTFC++ pro ty, kdož bez toho nemohou dýchat
- pouze externí const: tady mi smysl poněkud uniká; v čem tkví pointa?
- argumenty ohledně lenosti více psát jsou už dávno ve skutečnosti pouze neschopnosti efektivně používat textový editor; tato vlastnost C mně osobně nijak nechybí, ale ničemu by to asi nevadilo; u koho má takováto věc výrazný vliv na jeho produktivitu by se měl vážně zamyslet nad svými coding practices
- množiny: to mi taky nijak zásadně nikdy nechybělo, ono se to ani v tom Pascalu moc neujalo; ničemu by to asi nevadilo, kromě toho, že by to skoro nikdo nepoužíval, což je asi i důvod, proč to v C není
Ono jde o abstrakci. Problém je třeba řešit na úrovni, na které existuje. Když dělám komunikační protokol, tak musím vědět, po jaké jedu lince - např. UART_write(), ... Nenapíšu to dost abstraktně na to, abych nemusel nic měnit. A ovlivní to někdy celkem dost věcí, takže potom jsou na řadě zvěrstva jako psaní wrapperu, struktura s referencema na funkce, balení do maker,... Volbou namespace a automatickým výběrem funkce s odpovídajícím chováním by se hodně věcí vyřešilo.
Výjimky jsou sice prasárna, ale nepotřebuje tak moc zásobníku ve standardu. Ono třeba udělat několik nezávislých instancí hierarchovckýho stavovýho automatu a v něm mimo stavu reportovat chyby je docela divočina. Co je tam chyba návrhu? Stavový automat, ošetření chyby, nebo absence výjimek (a ne, pokud je každá instance parseru v jiným vlákně pod FreeRTOS, tak setjmp nepomůže).
S čistotou enumu, nebudem si lhát. Mimo cyklu (kde stejně musím mít napsanou poslední položku známýho jména, abych věděl, kolik jich je, protože něco jako countof(enum) nebo foreach neexistuje), je to jenom svázání symbolických jmen s hodnotou a datovým typem. I v tom blbým Pascalu můžu napsat
var x: array[mujenum] of Integer;
a když v C napíšu
int q[enum mujenum];
tak mě to pošle do ...
Vyložebně se enum hodí pro zobrazení symbolickýho jména v debuggeru. Jinak jeho použití kulhá.
Bitový enum chci právě proto, abych nemusel psát rovnítka v klasickým enumu, pokud ten vnitřní stav je složením několika hodnot (fmRead | fmWrite) A pokud jde o #define, to je věc preprocesoru, bez typové kontroly, bez varování,... takže čím méň, tím líp. Je to univerzální hack na věci, který jazyk neumí ve standardu.
Bitový pole u hardware je jakž takž OK. V dalším levelu, třeba parser protokolu, to přetáhnu na jinou platformu a jsem v pr...
Částečná definice struktury, to je dost zásadní věc. Při rozšíření struktury nebo smazání položky, která je inicializovaná na X místech, to háže nepěknou chybu. A někdy je problém na straně architektury ve VHDL u výrobce křemíku. Víš, jak by bylo krásný si třeba udělat instanci periferky jako const struct, inicializovat natvrdo a jenom zkopírovat, místo přiřazování registru po registru? Jenomže ti pitomci tuhle nechají 100B pauzu, támhle je u SPI2 registr, který u SPI1 není a u SPI3 má jinou funkci... A někdy (nemožnost rozšířit strukturu, nepodpora přetěžování) je výhodnější vzhledem ke spotřebě paměti použít jednu strukturu s pár položkama navíc. A na mojí úrovni se prostě nechci starat o to, že tam je potřeba vložit pět libovolných intů jako výplň navíc :(
Rozšíření struktur je celkem důležitá věc. Pokud mám několik modulů se stejným základem (např. různý komunikační linky) a u jedné chci přidat DMA, tak by pěkně odpadl wrapper, který pro společný funkce jako init() hodí strukturu zabalenou ve struktuře jako argument... Napsat to je práce navíc (i když #define to schová skoro bez zvýšení nároků).
Pouze externí const je za trest pro všechny, kdo nejsou schopní lokální proměnnou zapouzdřit jako static dovnitř modulu a kdokoliv se dostane bez varování kamkoliv. Aspoň by jednou museli přemýšlet.
A ta lenost má vliv vždycky. Když musím pro každý modul psát něco jako
#define write(data, size) UART_Write(handleWithDma->uart, data, size)
pro deset funkcí a zbytečně, tak to tak jako tak stojí čas a editor/IDE to za tebe neudělá...
Množiny, no ty jsem nepotřeboval už od včerejška :/ Zvyk je železná košila.
Jenomže ono to nesleduje nic. Prostě zase nějaký polodebil potřeboval ukázat, že umí vytáhnout data z vyhledávačů a rozpočítat do koláčovýho grafu bez ohledu na vypovídací hodnotu...
A on je taky rozdíl, jestli dá někdo "C programming" nebo "programování v C". Pokud se v tom indexu nezohlední jazyky, tak je stejně statistika jenom pro anglicky mluvící svět + nedefinovaný zlomek zbytku světa. Jakou takový index má přesnost? 1 sigma? Míň?
Stejně ve finále každej použije jazyk, který
a) Umí, třeba ze školy nebo z dřívějška
b) Je pro řešení problému nejvhodnější
c) Už je na projsktu, který upravuje, používán
"Basically the calculation comes down to counting hits for the search query +....."
Takže nepočítají oblíbenost, ale kolik o tom kterém jazyku lidi vyprodukují textu, resp. stránek, takže v podstatě jde o jazyk, o kterém se nejvíce publikuje a ne o tom, který jazyk se nejvíce používá, resp. je nejvíce oblíbený. Bylo by to dost silné tvrzení, že to, o čem je nejvíce textu je nejoblíbenější. Chápu to správně?
Docela ma prekvapilo ze je tam este Perl, to bude asi skor vdaka udrzbe existujucich systemov a skriptov.
Na druhu stranu docela zarazajuce je aj nizke percento c# a c++, aj ked pri c++ to az takym prekvapenim nieje ked sa clovek pozrie na jeho vyvoj a hlavne co okolo jednotlivych verzii sa stvara. Ten jazyk je uz tak prebujnely a prekomplikovany ze sam seba znici.
I kdybychom ignorovali to ze celej tento tiobe index je nic nevypovidajici, tak je potreba si uvedomit ze i on samotny nekolikrat zmenil (nekdy i nekolikrat behem roku) zpusob pocitani indexu. To znamena ze se vysledky mezi jednotlivymi hodnotami nedaji porovnavat. Takze cela tato zpravicka muze jit do /dev/null
Kazdy jazyk sa da sprasit vid http://www.ioccc.org/ Je to extrem ale jazyk vobec nezarucuje ze budete vediet pochopit kod.
Vysypeš z rukávu takový věci, jako setjmp.h? Bez nápovědy...
Jinak jako referenční manuál k C používám stránku http://www.cplusplus.com/reference/clibrary/ a nvíc skrz záložky, ne skrz vyhledávač... Asi jim to pěkně rozstřelí statistiku.
Nevysypu bez nápovědy skoro nic, dělám takový množství kravin, že po určité době nedokážu dát bez nápovědy kolikrát ani blbej if nebo for :D Ale na to mám v NB různý referenční manuály a knihy typu "Naučte se něco za 21 dní" a když se občas vracím k jazyku, kterej jsem dlouho nepoužil, tak do něčeho 10 minut koukám, abych se přepnul a pak už to jde samo :D Ale statistiku jim asi taky kazím no :D
Assembler je krásny primitívny a efektívny jazyk..A mimochodom vyťahovať dáta z vyhľadávačov a vyvádzať z nich závery je zjednodušovanie pohľadu na vec.To,že menej ľudí vyhľadáva info o jaz. C môže znamenať aj to,že mnohí sa ten jazyk už dávno naučili..Alebo si kúpili kvalitnú literatúru v kamennom obchode..A mimochodom je predsa samozrejmé,že ľudia budú vyhľadávať info o relatívne novších jazykoch(GO,Python..).Darmo,internetová idiocia :)
Ja už by som v C nerobil kým by som nemusel. Moc sa nekamarátim s moemory managmentom :D
Existuje jazyk bez virtualnej mašiny prípadne nejakého iného runtime v ktorom sa nemusím zaujímať o memory management a je memory-safe? Pozeral som čoto o Ruste ale neviem či je to to čo hladám. Viem že pointre sú základ prograovania... ale dá sa tam narobiť dosť chýb a hlavne som zlenivel na C# :D
A ďalej ma napadlo. Swift od Jablka si dosť pochvaľujú ale netuším či to má plne natívne binárky a keďže to jablko vydalo aj na Linux pripadá mi to dosť sympatické.
Memory management musite zohlednovat v kazdem jazyce, jen na jine urovni. To patri k praci dobreho softwaroveho inzenyra.
Rust se proslycha jako dobry systemovy jazyk bez GC. Nekteri dobri inzenyri si kupodivu oblibili Node.Js (s VM), ja k tomu nechci poskytovat zadny nazor, protoze jsem se tim nezabyval. Go podle nekterych s sebou nese velke casti Plan9 atd.
Ze zajimavych jazyku, ve kterych se da psat velmi vykonny kod je napr. Haskell, ale i SBCL (Lisp), pokud Vas tahne funcionalni programovani. Znam lidi, kteri jsou v Haskellu hodne produktivni a jejich kod je v mnoha smerech (dle meho soudu) kvalitni a pritom rychle napsany.
Lua sice jede na VM, ale ta VM je velmi kompaktni a da se jednoduse dostat do prakticky jakehokoliv programu jako knihovnicka, na rootu k tomu tusim byly clanky.
Dalsi lepici jazyky jako Python, Ruby, Perl snad i PowerShell apod. se muzou taky hodit na poradnou porci nasazeni. Asi jde o to, co nejvice potrebujete.