Dnes a zítra probíhá vývojářská konference Google I/O 2025. Sledovat lze na YouTube a na síti 𝕏 (#GoogleIO).
V Bostonu probíhá konference Red Hat Summit 2025. Vybrané přednášky lze sledovat na YouTube. Dění lze sledovat na síti 𝕏 (#RHSummit).
Společnost Red Hat oficiálně oznámila vydání Red Hat Enterprise Linuxu 10. Vedle nových vlastností přináší také aktualizaci ovladačů a předběžné ukázky budoucích technologií. Podrobnosti v poznámkách k vydání.
Tuto sobotu 24. května se koná historicky první komunitní den projektu Home Assistant. Zváni jsou všichni příznivci, nadšenci a uživatelé tohoto projektu. Pro účast je potřebná registrace. Odkazy na akce v Praze a v Bratislavě.
Troy Hunt představil Have I Been Pwned 2.0, tj. nový vylepšený web služby, kde si uživatelé mohou zkontrolovat, zda se jejich hesla a osobní údaje neobjevili v únicích dat a případně se nechat na další úniky upozorňovat.
Microsoft představil open source textový editor Edit bežící v terminálu. Zdrojové kódy jsou k dispozici na GitHubu pod licencí MIT.
V Seattlu a také online probíhá konference Microsoft Build 2025. Microsoft představuje své novinky. Windows Subsystem for Linux je nově open source. Zdrojové kódy jsou k dispozici na GitHubu pod licencí MIT.
Z příspěvku Turris Sentinel – co přinesl rok 2024 na blogu CZ.NIC: "Za poslední rok (únor 2024 – únor 2025) jsme zachytili 8,3 miliardy incidentů a to z 232 zemí a z jejich závislých území. Tyto útoky přišly od 6,2 milionu útočníků (respektive unikátních adres). SMTP minipot je stále nejlákavější pastí, zhruba 79 % útoků bylo směřováno na tento minipot, 16 % útoků směřovalo na minipot Telnet, 3 % útoků směřovaly na minipot HTTP a 2 % na minipot FTP. Dále jsme zaznamenali 3,2 milionu unikátních hesel a 318 tisíc unikátních loginů, které útočníci zkoušeli."
Byla vydána (Mastodon, 𝕏) nová verze 3.0.4 svobodné aplikace pro úpravu a vytváření rastrové grafiky GIMP (GNU Image Manipulation Program). Přehled novinek v oznámení o vydání a v souboru NEWS na GitLabu. Nový GIMP je již k dispozici také na Flathubu.
Byla vydána nová stabilní verze 7.4 webového prohlížeče Vivaldi (Wikipedie). Postavena je na Chromiu 136. Přehled novinek i s náhledy v příspěvku na blogu.
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: