Byla vydána nová verze 9.16 z Debianu vycházející linuxové distribuce DietPi pro (nejenom) jednodeskové počítače. Přehled novinek v poznámkách k vydání.
Americká vláda se po převzetí zhruba desetiprocentního podílu ve výrobci čipů Intel chystá na další investice do vybraných firem. Na sociální síti Truth Social to napsal prezident Donald Trump. Jeho ekonomický poradce Kevin Hassett v rozhovoru v televizi CNBC řekl, že nemusí jít pouze o firmy z technologického sektoru, ale i z jiných odvětví.
V Amsterdamu probíhá Open Source Summit Europe. Organizace Linux Foundation představuje novinky. Pod svá křídla převzala open source dokumentovou databázi DocumentDB.
Přesně před 34 lety, 25. srpna 1991, oznámil Linus Benedict Torvalds v diskusní skupině comp.os.minix, že vyvíjí (svobodný) operační systém (jako koníček, nebude tak velký a profesionální jako GNU) pro klony 386 (486), že začal v dubnu a během několika měsíců by mohl mít něco použitelného.
86Box, tj. emulátor retro počítačů založených na x86, byl vydán ve verzi 5.0. S integrovaným správcem VM. Na GitHubu jsou vedle zdrojových kódů ke stažení také připravené balíčky ve formátu AppImage.
Vláda Spojených států získala desetiprocentní podíl v americkém výrobci čipů Intel. Oznámili to podle agentur americký prezident Donald Trump a ministr obchodu Howard Lutnick. Společnost Intel uvedla, že výměnou za desetiprocentní podíl obdrží státní dotace v hodnotě 8,9 miliardy dolarů (zhruba 186 miliard Kč). Částka podle Intelu zahrnuje dříve přislíbené subvence 5,7 miliardy dolarů z programu CHIPS na podporu výroby čipů v USA,
… více »Organizace Apache Software Foundation (ASF) vydala verzi 27 integrovaného vývojového prostředí a vývojové platformy napsané v Javě NetBeans (Wikipedie). Přehled novinek na GitHubu. Instalovat lze také ze Snapcraftu a Flathubu.
Knihovna FFmpeg byla vydána ve verzi 8.0 „Huffman“. Přibyla mj. podpora hardwarově akcelerovaného kódování s využitím API Vulcan, viz seznam změn.
Národní úřad pro kybernetickou a informační bezpečnost (NÚKIB) vydal Zprávu o stavu kybernetické bezpečnosti ČR za rok 2024 (pdf). V loňském roce NÚKIB evidoval dosud nejvíce kybernetických bezpečnostních incidentů s celkovým počtem 268. Oproti roku 2023 se však jedná pouze o drobný nárůst a závažnost dopadů evidovaných incidentů klesá již třetím rokem v řadě. V minulém roce NÚKIB evidoval pouze jeden velmi významný incident a významných incidentů bylo zaznamenáno 18, což oproti roku 2023 představuje pokles o více než polovinu.
Byl publikován aktuální přehled vývoje renderovacího jádra webového prohlížeče Servo (Wikipedie). Servo mimo jiné nově zvládne animované obrázky APNG a WebP.
char& foo() { static char inner = 'a'; return a; }
Má tam být return inner;
foo() = 'b'; // přiřadí do proměnné inner 'b' cout << foo(); // vytiskne béčko Čili máme nádherný getter - setter, o kterém se žádnému javistovi ani nesníTo se od C liší jen ve hvězdičce před foo(), the C++ way by byla třída foo s operátorem=, operátorem<< pro ostream, konverzním operátorem na char a tak dál.
OK, neumím C, jaký je tedy rozdíl mezi polem a ukazatelem?
$ cat array.c #include <stdio.h> void f(char**p) { *p += 1; } int main() { char a[5] = "ahoj"; char *p = a; printf("a (%p): \"%s\"; p (%p): \"%s\"\n", a, a, p, p); f(&p); printf("a (%p): \"%s\"; p (%p): \"%s\"\n", a, a, p, p); f(&a); printf("a (%p): \"%s\"; p (%p): \"%s\"\n", a, a, p, p); return 0; } $ gcc -Wall array.c array.c: In function ‘main’: array.c:17: warning: passing argument 1 of ‘f’ from incompatible pointer type $ ./a.out a (0xbffc1d43): "ahoj"; p (0xbffc1d43): "ahoj" a (0xbffc1d43): "ahoj"; p (0xbffc1d44): "hoj" a (0xbffc1d43): "bhoj"; p (0xbffc1d44): "hoj"
char a[] = "Hello, world!"; char* p; p = a; /* OK */ a = p; /* nelze */ printf("sizeof(p) = %lu\n", sizeof(p)); printf("sizeof(a) = %lu\n", sizeof(a));
char a[] = "abcd"; char* b = "abcd"; a[0] = 'x'; // OK b[0] = 'y'; // viz nížeTohle je velice záludné a nebezpečné, protože to mnohé kompilátory neodhalí, a program někdy běží a jindy padá.
a
je normální pole vytvořené na zásobníku a inicializované příslušným řetězcem. Kdežto b
je ukazatel na konstantní řetězec (mělo by tedy správně být const char* b
). Kompilátory ale většinou dovolí (dokonce bez varování) použít nekonstantní pointer, a problémy se vyrojí až za běhu.
void funkce(char *parametr) { int i; for (i = 0; i < 256; i++) parametr[i] = 0; } void slozitejsi(char *pole[256]) { int i, j; for (i = 0; i < 256; i++) for (j = 0; j < 256; j++) pole[i][j] = 0; } int main() { char prvni_pole[256]; char *druhe_pole = (char *) malloc(256); char *treti_pole[256]; char **ctvrte_pole = (char **) malloc(256*sizeof(char *)); char pate_pole[256][256]; int i; for (i = 0; i < 256; i++) { treti_pole[i] = (char *) malloc(256); ctvrte_pole[i] = (char *) malloc(256); } /* toto se chová stejně */ funkce(prvni_pole); funkce(druhe_pole); /* tohle také */ slozitejsi(treti_pole); slozitejsi(ctvrte_pole); #if 0 /* tohle nejde */ slozitejsi(pate_pole); #endif return 0; }
Pole je uspořádana homogenní n-tice.Což vyžaduje kontrolu mezí, která jak známo v Céčku co? No není :) OK, pár příspěvků v této diskusi mne přesvědčilo o tom, že skutečně nelze zaměňovat pole a ukazatel. Ale na tom, že céčkovské pole není skutečné pole, trvám :)
Uspořádáná homogenní n-tice samozřejmě kontrolu mezí nutně nevyžaduje.Pětice, která mi je ochotna vrátit svůj šestý (nebo nedej bože mínus prvý) prvek podle mne není pětice, nýbrž hodně divný způsob nepřímého přístupu k paměti (ukazatel ;) ).
begin end.
blok. Tato věc mi v C chyběla.
static void __attribute__((constructor)) je_mi_smutno_po_begin_end_bloku() { /* něco si tu udělám */ }Ale není to moc podle normy... V C++ lze dělat i takovéto skopičiny. (Pro zajímavost přikládám celý program, který je inspirován tímto zadáním: http://www.fi.muni.cz/usr/jkucera/pb161/color.htm)
#include <iostream> #include <string> using namespace std; class ColorMap { private: ColorMap(); public: static ColorMap colormap; static const int colorcount; static char colors[]; static int inv_colors[256]; }; const int ColorMap::colorcount = 8; char ColorMap::colors[] = "KRGYBMCW"; int ColorMap::inv_colors[256]; ColorMap ColorMap::colormap; ColorMap::ColorMap() { int i; for (i = 0; i < 256; i++) inv_colors[i] = -1; for (i = 0; i < colorcount; i++) { inv_colors[static_cast<int>(colors[i])] = i; inv_colors[static_cast<int>(colors[i]) + 0x20] = i; } } class color { public: color(const char _color = 'K') : color_int(ColorMap::inv_colors[static_cast<int>(_color)]) { } color(const color& _color) : color_int(_color.color_int) { } color operator+ (const color& c) const { color newcolor(*this); newcolor.color_int |= c.color_int; return newcolor; } color operator* (const color& c) const { color newcolor(*this); newcolor.color_int &= c.color_int; return newcolor; } friend std::ostream& operator<< (std::ostream& s, const color c) { return s << ColorMap::colors[c.color_int]; } friend std::istream& operator>> (std::istream& s, color& c) { char _color; int color_int; while (s >> _color) { if ((color_int = ColorMap::inv_colors[static_cast<int>(_color)]) >= 0) { c.color_int = color_int; break; } cout << "Zadání barvy bylo chybné, zadejte, prosím, jedno z písmen " << ColorMap::colors << ": "; } return s; } int color_int; private: };
Třeba v STL by se pár užitečných příkladů našlo.
No, zas tak hrozné to snad není. Já v tom udělal asi 10k program a šlapalo to, když se člověk vyhnul šablonám. Jak by řekl klasik: Když víš, které konstrukce způsobují interní chybu překladače, můžeš v pohodě programovat.V mém případě tou konstrukcí bylo
if
. A programovat bez if
je velmi obtížné.
V BCB jsem narazil ještě na jedu krásnou chybu. Při debugování se po najetí myší nad proměnnou zobrazí v bublině její hodnota. Problém byl, když ta proměnná byl integer ve tvaru i++ nebo ++i. Pak to nejen zobrazilo hodnotu, ale rovnou to číslo i inkrementovalo. Takže po prvním najetí tam bylo 1, pak 2, 3 atd. Trvalo mi pár hodin, než jsem na to přišelNaštěstí jsem v té době ještě byl zvyklý debugger nepoužívat (jedine pro post-mortem). Bohužel jsem od té doby vyměkl.
Já vím, že se dočkám. Naštěstí existuje Microsoft, který se svým .NET prostředím dokázal to, co jsem si dlouhá léta myslel, že nebude možné. A to probudit Sun ze svého bahýnka sebechvály na Javu a ukázat, že Java má co zlepšovat. Takže jsem se třeba dočkal šablon, autoboxu a věřím, že se dočkám i operátorů.To se snad nikdy nestane. Bohatě stačí již udělané boty. Zvláště autoboxing+autounboxing .
==
. Přesněji to, že je přetížený a má dvě zcela rozdílné funkce: buď porovnává hodnoty (u primitivních typů) nebo reference (u objektů). Typická ukázka, kam vede přetěžování operátorů...
Správně by měly být operátory dva: jeden pro porovnání hodnoty, druhý pro porovnání referencí.
Viz Python a operátory '==' a operátor 'is'. Ale nejlepší řešení je runtime systém který zaručuje že totožné integery nebo totožné stringy mají identické reference, pak není druhý operátor opravdu potřeba.Jistě. Ale to se motáme pořád dokola - že primitivní typy do opravdu objektového jazyka nepatří. Nu, co se dá dělat... Mnohem víc mi ale v Javě chybí metody tříd.
Mnohem víc mi ale v Javě chybí metody tříd.Možná mi něco uniklo, ale mám li třeba třídu:
public class Trida { private final int a = 5; // metoda tridy public static int vratA() { return(this.a); } }Tak potom můžu volat metodu třídy takto:
int moje_a = Trida.vratA()
Tedy alespoň ve všech učebnicích Javy se tomuto volání říká volání metody třídy. Ale možná si měl na mysli něco jiného.
this
sem si nebyl jistej. Ale je pravda, že o metodách třídy i o metodách instance se zmiňuje pan Herout ve své (dle mne docela dobré) knize "Učebnice jazyka Java".
Ale o to jde. Java prostě zvolila špatnou cestu. Dokonce i Microsoft, když tvořil svůj .NET toto podstatně zdokonalil, i když také zůstal na půl cesty. U .NET existuje daleko více primitivních typů, ale všechno je objektem. I int je objektem a třeba konstrukce 123.ToString() je v C# platná. Stejně tak to funguje třeba ve Smalltalku, nebo v jiných, opravdu objektových jazycích.Ale prdlajs. C# převzalo primitivní typy z Javy, jenom tam dali autoboxing/autounboxing hned.. Pravda je, že je to daleko více zaintegrované a programátor o tom ani nemusí vědět... do jisté míry. Více viz například zde Uznávám že se to dá brát jako podstatné zdokonalení.
Pak je pro Javu autoboxing jenom dalším prvkem bordelu, který tam vnesla. Prostě Java se jenom topí v bordelu, který si způsobila tím, že neprohlásila promitivní typy za objekty, což by jí nic nestálo a bylo by to efektivnější řešení.No jo, dneska se to lehko mluví, když to víme... Ale jak jsem již zmínil, asi by to bylo rozhodnutí správné technicky, ale velmi špatné politicky.
V C++ neexistuje problém tohoto typu. V C++ je naprosto jasné z použití operátorů, zda porovnáváte hodnotu, nebo adresu. Operátory == a != v C++ vždycky porovnávají hodnotu.To je nějaký fór? Schválně jsem se podíval, a
==
i !=
by měly být přetížitelné.
Ale je to perfektní ukázka toho, co je na přetěžování operátoru špatného: i když se může zdát že je zcela bezpečné, stejně o něj člověk zakopne a rozbije si hubu. I kdyby to bylo za 10 let.
A co jste taktně ignoroval byla moje poznámka, že v C# neexistují nic než objekty. Tedy neexistuje, že by třeba int nebyl objekt, jako je tomu třeba v Javě.Pokud budeme hodnotové typy považovat za objekty - pak je to ovšem jen otázka terminologie. Nebo pokud přistoupíme na to, že boxing/ungoxing je zcela transparentní (což není). Ani s jedním nesouhlasím. Nelze situaci v C# srovnávat se Smalltalkem, CLOS či dalšími - sice se to tak napůl tváří, ale ne zcela.
No jo, dneska se to lehko mluví, když to víme... Ale jak jsem již zmínil, asi by to bylo rozhodnutí správné technicky, ale velmi špatné politicky. Vědělo se to už tehdy. Už tehdy existovaly objektové jazyky, které měly všechny typy jako objekty. Otázkou je, jak říkáte, co bylo průchodné politicky.Přesně to jsem měl na mysli.
A druhak váš důkaz není nic jiného, než co můžete provést s jakoukoli vlastností programovacího jazyka.Jednak nebyl žádný důkaz, jenom poznámka mimochodem. Druhak jsem jasně napsal, že měly být vytvořeny operátory dva, jak se ukázalo při rozšiřování. Přetěžování operátorů je velmi kontroverzní věc a v podstatě se nedá vyřešit (flamewar není řešení). Každopádně je zcela proti základní filozofii jazyka Java a nepatří tam. Přidáváním takovýchto featur by se z toho stal úplně jiný jazyk.
V javě je dokonce operátor klíčové slovoV Javě jsou (neimplementovaná) klíčová slova goto a const, ale o klíčovém slovu operator slyším prvně. Našel jsem akorát tohle: http://jira.opensymphony.com/browse/WF-281, na java.sun.com ani slovo.
třeba se dočkášDoufám že ne, úplně mi stačí statické importy a auto(un)boxing :) Jsem rád, že Anders Hejlsberg dělá na .NETu a ne na Javě :)
Cynická poznámka: nevzniklo takhle nějak céčko? :-)
#include <iostream> #include "pretizeni.h" using namespace std; main() { int a = 3; int b = 4; cout << (a + b) << endl; return 0; }I když to zní divně, tak vypíše
-1
. Je poněkud vylepšen hlavičkovým souborem pretizeni.h
:
#ifndef __PRETIZENI_H #define __PRETIZENI_H #include <ostream> class INT { public: INT() : hodnota(0) { } INT(int _hodnota) : hodnota(_hodnota) { } friend INT operator+ (INT&, INT&); friend INT operator- (INT&, INT&); friend std::ostream& operator<< (std::ostream&, INT&); friend std::ostream& operator<< (std::ostream&, INT ); private: int hodnota; }; INT operator+ (INT& a, INT& b) { return INT(a.hodnota-b.hodnota); } INT operator- (INT& a, INT& b) { return INT(a.hodnota+b.hodnota); } std::ostream& operator<< (std::ostream &s, INT& a) { return s << a.hodnota; } std::ostream& operator<< (std::ostream &s, INT a) { return s << a.hodnota; } #define int INT #endif
int hodnota
, si můžu inicializovat klidně i vevnitř a normálně, zatímco běžné objekty jdou jen před konstruktorem. Ještě můžu mít tu smůlu, že na sobě nějak závisí. To už pak je rovnou lepší použít ukazatele, new
a delete
.
P.S.: Ve výše uvedeném příkladu jsem ještě jaksi zapomněl v operátoru <<
použít const INT&
, takže jsem jej zavedl dvakrát. To mám z toho ponocování. Přetěžování operátorů je ještě celkem srozumitelné. Skutečné depresi jsem propadl až tehdy, když jsem objevil pointery na metody… :-)
#include <iostream> class T { public: T() {}; void ma(int x) { std::cout << "T::ma(" << x << ")\n"; } void mb(int x) { std::cout << "T::mb(" << x << ")\n"; } }; typedef void (T::*method_pointer)(int); void call(T* x, method_pointer m, int n) { (x->*m)(n); } int main() { T x; call(&x, &T::ma, 1); call(&x, &T::mb, 2); }
class Trida { public: void metoda(void); } instance; void Trida::metoda(void) { printf("To JE ale prasarna!\n"); } void (Trida::*funkce(void))(void) { return Trida::metoda; } void main() { void (Trida::*uk)() = funkce(); (instance.*uk)(); }
const dsql_nod* const* const end:-)
Zkoušeno pod BCB, MSVC, GCC. Možná je to dáno závazným způsobem vyhodnocení té konstrukce, nevím.Chtělo by to nahlédnout to K&R Bible. Jestli zítra (vlastně už dnes...) vzpomenu.
Tiskni
Sdílej: