Единственото предимство, което мисля, че bzero()
има пред memset()
за настройка на паметта на нула, е, че има намален шанс да бъде направена грешка.
Повече от веднъж съм попадал на грешка, която изглеждаше така:
memset(someobject, size_of_object, 0); // clear object
Компилаторът няма да се оплаче (въпреки че може би вдигането на някои нива на предупреждение може да се случи при някои компилатори) и ефектът ще бъде, че паметта не се изчиства. Тъй като това не изхвърля обекта в боклук - просто го оставя сам - има приличен шанс грешката да не се прояви в нещо очевидно.
Фактът, че bzero()
не е стандартен, е малък дразнител. (FWIW, не бих се изненадал, ако повечето извиквания на функции в моите програми са нестандартни; всъщност писането на такива функции е нещо като моя работа).
В коментар към друг отговор тук, Арън Нютон цитира следното от Unix Network Programming, Том 1, 3-то издание от Stevens, et al., Раздел 1.2 (курсивът е добавен):
bzero
не е ANSI C функция. Произлиза от ранния мрежов код на Berkely. Въпреки това, ние го използваме в целия текст, вместо функцията ANSI C memset
, тъй като bzero
се помни по-лесно (само с два аргумента), отколкото memset
(с три аргумента). Почти всеки доставчик, който поддържа API за гнезда, също предоставя bzero
, а ако не, ние предоставяме дефиниция на макрос в нашата заглавка unp.h
.
Наистина, авторът на TCPv3 [TCP/IP Illustrated, Volume 3 - Stevens 1996] направи грешката да размени втория и третия аргумент на memset
в 10 пъти при първото отпечатване. C компилаторът не може да улови тази грешка, защото и двата аргумента са от един и същи тип. (Всъщност вторият аргумент е int
, а третият аргумент е size_t
, което обикновено е unsigned int
, но посочените стойности, съответно 0 и 16, все още са приемливи за другия тип аргумент.) Извикването на memset
все още работи , тъй като само няколко от функциите на сокета всъщност изискват последните 8 байта от адресна структура на интернет сокет да бъдат зададени на 0. Независимо от това, това беше грешка и такава, която можеше да бъде избегната чрез използване на bzero
, тъй като размяната на двата аргумента на bzero
винаги ще бъде уловен от C компилатора, ако се използват прототипи на функции.
Също така вярвам, че по-голямата част от обажданията към memset()
са до нулева памет, така че защо да не използвате API, който е пригоден за този случай на употреба?
Възможен недостатък на bzero()
е, че компилаторите може да са по-склонни да оптимизират memcpy()
, защото е стандартен и затова може да са написани да го разпознават. Имайте предвид обаче, че правилният код все още е по-добър от неправилния код, който е оптимизиран. В повечето случаи използването на bzero()
няма да причини забележимо въздействие върху производителността на вашата програма и това bzero()
може да бъде макрос или вградена функция, която се разширява до memcpy()
.
person
Michael Burr
schedule
13.06.2013
memset
може да е малко по-малко ефективен поради малко повече проверки, определено е случай на преждевременна оптимизация: каквито и да са ползите, които можете да видите от пропускането на една или две инструкции на процесора, не си заслужават, когато можете да застрашите преносимостта на вашия код .bzero
е остарял и това е достатъчна причина да не го използвате. - person Sergey Kalinichenko   schedule 14.06.2013