Spíš proč nepoužívat některé funkce ze standardní knihovny C.
Nicméně někteří lidé, co píší v C, si už napsali vlastní knihovny, kde je tohle a mnoho dalších věcí vyřešených lépe.
Podívejte se třeba jak píše v C Ryan Fleury případně Eskil Steenberg. Ten první je mi bližší, ale oba mají blogy nebo přednášky, kde ukazují, jak v C psát funkční a efektivní kód.
Takže standardní knihovna céčka vlastně stačí tak k tomu, aby si každý programátor/projekt implementoval vlastní nadstandardní knihovnu. Rozumím té motivaci - programátor ví nejlíp, jakou implementaci pro ten který problém zvolit a jaké okrajové podmínky musí dodržet... ale.
Umět s céčkem ale znamená umět nejenom syntax, ale i všechny nadsyntaktické možnosti a pasti preprocesoru; schopnosti standardní knihovny a také její neschopnosti - protože jazyk a standardní knihovna mají dost omezené schopnosti bezpečného selhání a konkrétní implementace mají možnost udělat eval(UB) místo panic(UB); a k tomu veškerý tooling a konvence toho kterého projektu - nadstandardní knihovnou počínaje a specifickými instrukcemi pro formátování kódu konče.
To není zrovna dobrá vizitka - i přes všechny výhody, které přístup "každý sám za sebe" přináší stran stability, nezávislosti a údržby.
naštěstí to neplatí pro c++. A pokud si v C++ píše vlastní std::string, tak nejspíš neumí C++ ale C a C++ prolistoval při jízdě rychlíkem
Navyše sa niekedy vtipne hovorí, že každý pokročilý programátor v C má napísané svoje vlastné C++. Zatiaľ čo programátori v C++ používajú štandardné C++. Ale to len tak medzi rečou.
Dokážu si představit pár situací, kdy by dávalo smysl psát vlastní std::string. Ale řekl bych, že se do nich v tomhle životě nedostanu :)
To jo. Ale je rozdíl ten vlastní string psát nebo zdědit. Tam pak není třeba aby ten vlastní string byl lepší, nebo dokonce dobrý. A často dává spíš smysl ho vyrazit, jen to není tak jednoduché.
6. 1. 2026, 10:19 editováno autorem komentáře
Abyste ho mohl „vyrazit“ musíte velmi dobře znát jak tu vlastní/zděděnou implementaci, tak také ten standard, mít unit testy a tak dále. A pak musíte mít koule tuhle nebezpečnou taškařici v teamu prosadit. To nebývá moc lehké…
Vím vím. Jednou jsem kuchal takový zabugovaný string a nahrazoval jeho vnitřnosti std stringem. Řádově jednodušší, ale stejně nastávaly zajímavé věci.
Naštěsti se dá spolehnout na to, že std::string programátoři +- znají. Takže jde používat v novém kódu std::string a řešit staré stringy jen na jeho hranici. Ta dodatečná složitost se dá zkousnout, za cenu toho, že ten starý string pomaličku mizí.
No já jsem právě viděl tu diskusi pod původním blog postem a tam navrhovali používat nějakou funkci ze specifikace C11. Co je teda teď best practice ve standardní knihovně C (používají prý C98)?
ISO C11 (Annex K) podporuje vlastně jen Microsoft.
BSD/macOS má vlastní strlcpy().
Jinak: https://www.open-std.org/jtc1/sc22/wg14/www/docs/n1967.htm
Existuje. Funkce strlcpy() je součástí glibc 2.38. Což je ale pro mnohé dost čerstvá verze, myslím, že je v distrech jako Fedora 39+, RHEL 10, Ubuntu 23.10+ apod.
#ifndef strlcpy
#define strlcpy(a,b,c) .....
#endif
Pokud to není kritické na rychlost, stačí i naivní oneliner, pokud je, tak kopírnout z BSD kde to je už pěkných pár desetiletí. Nebo strcpy_s()
5. 1. 2026, 15:17 editováno autorem komentáře
Pořád jsou to jen pojídači koláčů. Skutečný programátor nepíše v C, píše ve FORTRANu a používá GOTO.
Treba MS v C mam tyhle funkce s osetrenim delky bufferu v ramci standardni knihovny snad uz 20 let...
No nevim, tenhle hate kdyz tu mame https://linux.die.net/man/3/strlcpy ale proc si nekopnout...
Protože strlcpy se sice na rozdíl od dá použít bezpečně, ale furt to není nic jistého. Vždyť i vámi odkazovaný manuál zmiňuje, že se jeho autoři na první pokus sekli.
A tohle je jenom kopie. Nic specificky stringového. Jen něco, co umí vlastně všechny normální datové typy. A navrch je někde strlcpy a jinde zas strcpy_s.
V normálním jazyce by strlcpy a spol byla ostuda a dobrý důvod pro hate. Ale tohle je C.
No C jsem dávno opustil právě proto, že už přes 30 let nezmodernizovalo svou standardní knihovnu
- já vím, je to posix knihovna, ale proč sakra tedy neschváli nějakou vlastní, bezpečnou?
Ale POSIX má modernější a bezpečné varianty funkcí, ale ty staré tam z důvodu kompatibility musí zůstat, a to poměrně hodně dlouho. Je z toho pak trochu zmatek v dokumentaci.
Kompilátory (clang i gcc) a analyzátory (např. SonarQube) dokonce zobrazují warningy o deprecated/unsafe funkcích, ale je fakt, že ke skutečnému odstranění snad nikdy nedošlo.
Takže je to na programátorech, buď jim je to jedno a použíjí jednoduhé/nebezpečné funkce nebo prostě mají zájem na modernizaci kódu a ten kód skutečně modernizují.
Na druhou stranu jeste ze k tomu odstraneni nedoslo. Warning je OK, nepouzivat to s user provided stringy je taky standard, ale je spousta validnich use-case, kdy je to bezpecne i rychle - treba s->field = safemalloc(strlen(string)+1); strcpy(s->field, string) ; plus zpetna kompatibilita.
Ono staci to peklo, ktere rozpoutala ve starsich projektech c23 :(
Rychlé? Volá se tam strlen. Rychlé je memcpy. A bezpečností je na tom nastejno se strcpy, možná i líp.
strcpy se dá použít bezpečně jen v situacích, kdy ho jde triviálně nahradit pomocí memcpy. Když neznám předem délku stringu, tak je to past.
BTW, i ten strlen není úplně cajk. On tam ten zero terminátor být nemusí a strlen to nepozná. A pak ten string copy může útočníkovi naservírovat nějaká cizí data.
The strncpy() function is similar, except that at most n bytes of src are copied. Warning: If there is no null byte among the first n bytes of src, the string placed in dest will not be null-terminated.
To je z bláta do louže :-D
Je ale třeba si uvědomit (a moc se to neví), že strncpy nikdy neměla sloužit jako bezpečný strcpy pro C-type stringy, ale výlučně pro vytvoření fixed size stringu (nebo jak se tomu správně nadává).
Dlužno podotknout, že jsem v tomhle tisíciletí viděl přesně dva projekty, které tuhle formu používají (resp posílají po síti).
<hr />
The C library strncpy() function accepts three parameters(dest, src, n) which copies up the n characters from the string pointed to, by src to dest. In this case, the length of src is less than that of n, the remainder of dest will be added with null bytes.
6. 1. 2026, 04:29 editováno autorem komentáře