ทำไมต้องใช้ bzero มากกว่า memset?


156

ในคลาสการเขียนโปรแกรมระบบที่ฉันเอาภาคการศึกษาก่อนหน้านี้เราต้องใช้ไคลเอนต์ / เซิร์ฟเวอร์ขั้นพื้นฐานในซีเมื่อเริ่มต้น structs เช่นsock_addr_inหรือบัฟเฟอร์บัฟเฟอร์ (ที่เราใช้ในการส่งข้อมูลไปมาระหว่างไคลเอนต์และเซิร์ฟเวอร์) อาจารย์ สั่งให้เราใช้เท่านั้นbzeroและไม่memsetเริ่มต้นพวกเขา เขาไม่เคยอธิบายว่าทำไมและฉันอยากรู้ว่ามีเหตุผลที่ถูกต้องสำหรับสิ่งนี้หรือไม่?

ฉันดูที่นี่: http://fdiv.net/2009/01/14/memset-vs-bzero-ultimate-showdownที่bzeroมีประสิทธิภาพมากขึ้นเนื่องจากความจริงที่ว่าจะเป็นศูนย์ความจำเท่านั้นดังนั้นมันจึงไม่ ต้องทำการตรวจสอบเพิ่มเติมใด ๆ ที่memsetอาจทำ ที่ยังคงไม่จำเป็นต้องดูเหมือนเหตุผลที่จะไม่ใช้อย่างแน่นอนmemsetสำหรับหน่วยความจำ zeroing

bzeroถือว่าเลิกใช้แล้วและไม่ใช่ฟังก์ชัน C มาตรฐาน ตามคู่มือmemsetเป็นที่ต้องการมากกว่าbzeroด้วยเหตุผลนี้ ดังนั้นทำไมคุณยังต้องการใช้bzeroมากกว่าmemset? เพื่อประสิทธิภาพที่เพิ่มขึ้นหรือเป็นอะไรที่มากกว่านี้หรือ ในทำนองเดียวกันสิ่งที่มีประโยชน์memsetมากกว่าbzeroที่ทำให้มันเป็นตัวเลือกที่ต้องการโดยพฤตินัยสำหรับโปรแกรมที่ใหม่กว่า?


28
"ทำไมต้องใช้ bzero มากกว่า memset" - ไม่ต้อง Memset เป็นมาตรฐานไม่ใช่ศูนย์

30
bzero เป็น BSDism () memset () คือ ansi-c ปัจจุบัน bzero () อาจถูกนำมาใช้เป็นแมโคร ขอให้อาจารย์ของคุณโกนตัวเองและอ่านหนังสือ ประสิทธิภาพเป็นข้อผิดพลาดปลอม syscall หรือ context-switch สามารถทำเครื่องหมายค่านาฬิกานับหมื่นได้อย่างง่ายดายหนึ่งผ่านการบัฟเฟอร์ทำงานที่ความเร็วบัส หากคุณต้องการเพิ่มประสิทธิภาพโปรแกรมเครือข่าย: ลดจำนวนของ syscalls (โดยการอ่าน / เขียนชิ้นขนาดใหญ่)
wildplasser

7
แนวคิดที่memsetอาจมีประสิทธิภาพน้อยกว่าเล็กน้อยเนื่องจาก "การตรวจสอบเพิ่มเติมเล็กน้อย" เป็นกรณีของการปรับให้เหมาะสมก่อนกำหนด: สิ่งที่คุณเห็นจากการละเว้นคำสั่งซีพียูหรือสองอย่างนั้นไม่คุ้มค่าเมื่อคุณเสี่ยงต่อการพกพาของคุณ รหัส. bzeroล้าสมัยและนั่นเป็นเหตุผลเพียงพอที่จะไม่ใช้
dasblinkenlight

4
บ่อยครั้งคุณสามารถเพิ่ม initializer `= {0}` แทนและไม่เรียกใช้ฟังก์ชันเลย เรื่องนี้จะง่ายขึ้นเมื่อประมาณศตวรรษที่ C ต้องหยุดการประกาศตัวแปรเฉพาะที่ล่วงหน้า ถึงกระนั้นกระดาษเก่าที่แท้จริงยังคงติดอยู่ลึกลงไปในศตวรรษที่แล้ว
MSalters

1
@SSAnne no แต่มันน่าจะมาจากหนังสือแนะนำสำหรับหลักสูตรที่เขาได้รับอิทธิพลตามที่กล่าวไว้ในหนึ่งในคำตอบด้านล่าง: stackoverflow.com/a/17097072/1428743
PseudoPsyche

คำตอบ:


152

ผมไม่เห็นเหตุผลใด ๆ จะชอบมากกว่าbzeromemset

memsetเป็นฟังก์ชัน C มาตรฐานในขณะที่bzeroไม่เคยเป็นฟังก์ชันมาตรฐาน C เหตุผลอาจเป็นเพราะคุณสามารถบรรลุฟังก์ชั่นเดียวกันโดยใช้memsetฟังก์ชั่น

ตอนนี้เกี่ยวกับประสิทธิภาพคอมไพเลอร์เช่นgccใช้ builtin implementations memsetซึ่งเปลี่ยนไปใช้งานเฉพาะเมื่อ0ตรวจพบค่าคงที่ เช่นเดียวกับglibcเมื่อ buildins ถูกปิดใช้งาน


ขอบคุณ มันสมเหตุสมผลแล้ว ฉันค่อนข้างแน่ใจว่าmemsetควรใช้ในกรณีนี้เสมอ แต่ก็สับสนว่าทำไมเราถึงไม่ใช้มัน ขอบคุณสำหรับการชี้แจงและยืนยันความคิดของฉัน
PseudoPsyche

1
ฉันมีปัญหามากมายเกี่ยวกับbzeroการใช้งานที่ไม่สมบูรณ์ ในอาร์เรย์ที่ไม่จัดแนวมันเคยใช้งานเกินขนาดความยาวที่กำหนดและไม่มีไบต์เหลืออีกสักเล็กน้อย memsetไม่เคยมีปัญหาดังกล่าวหลังจากที่เปลี่ยนไป
rustyx

อย่าลืมmemset_sว่าควรใช้แบบไหนหากคุณต้องการให้แน่ใจว่าคอมไพเลอร์ไม่ปรับการเรียกหน่วยความจำ "ขัด" อย่างเงียบ ๆ เพื่อวัตถุประสงค์ที่เกี่ยวข้องกับความปลอดภัย ชิ้นส่วนของข้อมูลเช่นรหัสผ่าน cleartext)
Christopher Schultz

69

ฉันเดาว่าคุณใช้ (หรืออาจารย์ของคุณได้รับอิทธิพลจาก) การเขียนโปรแกรมเครือข่าย UNIXโดย W. Richard Stevens เขาใช้งานbzeroบ่อยๆแทนที่จะเป็นmemsetฉบับล่าสุด หนังสือเล่มนี้เป็นที่นิยมมากฉันคิดว่ามันเป็นสำนวนในการเขียนโปรแกรมเครือข่ายซึ่งเป็นสาเหตุที่คุณยังคงเห็นมันใช้อยู่

ฉันจะติดmemsetเพียงเพราะbzeroเลิกและลดการพกพา ฉันสงสัยว่าคุณจะเห็นกำไรที่แท้จริงจากการใช้อันใดอันหนึ่ง


4
คุณจะถูกต้อง เราไม่จำเป็นต้องมีหนังสือเรียนสำหรับหลักสูตรนี้ แต่ฉันเพิ่งตรวจสอบหลักสูตรอีกครั้งและการเขียนโปรแกรมเครือข่าย UNIXถูกระบุว่าเป็นทรัพยากรทางเลือก ขอบคุณ
PseudoPsyche

9
มันแย่กว่านั้นจริงๆ มันเลิกใช้แล้วใน POSIX.1-2001 และถูกลบใน POSIX.1-2008
paxdiablo

9
การอ้างถึงหน้า 8 ของการเขียนโปรแกรมเครือข่าย UNIXรุ่นที่สามโดย W. Richard Stevens - ผู้เขียน TCPv3 ทำผิดพลาดในการสลับอาร์กิวเมนต์ที่สองและสามเพื่อ memset ใน 10 ครั้งของการพิมพ์ครั้งแรก AC compiler ไม่สามารถจับข้อผิดพลาดนี้ได้เนื่องจากทั้งสองเหตุการณ์เหมือนกัน ... มันเป็นข้อผิดพลาดและสามารถหลีกเลี่ยงได้โดยใช้ bzero เนื่องจากการแลกเปลี่ยนสองอาร์กิวเมนต์ไปยัง bzero จะถูกจับโดยคอมไพเลอร์ C เสมอหากใช้ฟังก์ชันต้นแบบ อย่างไรก็ตามเมื่อ paxdiablo ชี้ให้เห็น bzero ถูกคัดค้าน
Aaron Newton

@AaronNewton คุณควรเพิ่มคำตอบของ Michaelลงไปเพื่อยืนยันสิ่งที่เขาพูด
Synetech

52

ข้อดีอย่างหนึ่งที่ฉันคิดว่าbzero()มีมากกว่าmemset()สำหรับการตั้งค่าหน่วยความจำให้เป็นศูนย์คือมีโอกาสลดข้อผิดพลาดที่เกิดขึ้น

มากกว่าหนึ่งครั้งฉันเจอข้อผิดพลาดที่ดูเหมือน:

memset(someobject, size_of_object, 0);    // clear object

คอมไพเลอร์จะไม่บ่น (แม้ว่าอาจจะเพิ่มระดับคำเตือนในคอมไพเลอร์บางตัว) และเอฟเฟกต์จะทำให้หน่วยความจำไม่ได้ถูกล้าง เพราะสิ่งนี้ไม่ได้ทำลายวัตถุ แต่ทิ้งไว้คนเดียว - มีโอกาสดีที่ข้อผิดพลาดอาจไม่ปรากฏในสิ่งที่ชัดเจน

ความจริงที่bzero()ไม่ได้มาตรฐานเป็นสิ่งที่ทำให้ระคายเคืองเล็กน้อย (FWIW ฉันจะไม่แปลกใจถ้าการเรียกใช้ฟังก์ชันส่วนใหญ่ในโปรแกรมของฉันไม่ได้มาตรฐาน แต่อันที่จริงการเขียนฟังก์ชั่นดังกล่าวเป็นงานของฉัน)

ในความคิดเห็นถึงคำตอบอื่น ๆ ที่นี่ Aaron Newton อ้างถึงสิ่งต่อไปนี้จาก Unix Network Programming, Volume 1, 3rd Edition โดย Stevens, et al., Section 1.2 (เน้นการเพิ่ม):

bzeroไม่ใช่ฟังก์ชัน ANSI C มันมาจากรหัสเครือข่าย Berkely ก่อน อย่างไรก็ตามเราใช้มันตลอดทั้งข้อความแทนที่จะเป็นmemsetฟังก์ชั่นANSI C เพราะbzeroง่ายต่อการจดจำ (มีเพียงสองข้อโต้แย้ง) กว่าmemset(มีสามข้อโต้แย้ง) ผู้ขายเกือบทุกรายที่สนับสนุน sockets API ก็มีให้bzeroเช่นกันและหากไม่มีเราจะให้คำจำกัดความของแมโครในunp.hส่วนหัวของเรา

อันที่จริงผู้เขียนของ TCPv3 [TCP / IP ภาพประกอบเล่ม 3 - สตีเว่น 1996] ทำผิดพลาดในการแลกเปลี่ยนข้อโต้แย้งที่สองและสามไปmemsetใน 10 ที่เกิดขึ้นในการพิมพ์ครั้งแรก คอมไพเลอร์ AC ไม่สามารถตรวจจับข้อผิดพลาดนี้ได้เนื่องจากอาร์กิวเมนต์ทั้งสองเป็นชนิดเดียวกัน (ที่จริงแล้วอาร์กิวเมนต์ที่สองคือintและอาร์กิวเมนต์ที่สามคือsize_tซึ่งโดยทั่วไปจะเป็นunsigned intแต่ค่าที่ระบุคือ 0 และ 16 ตามลำดับยังคงเป็นที่ยอมรับสำหรับอาร์กิวเมนต์ประเภทอื่น) การเรียกใช้memsetยังคงทำงานได้เนื่องจาก ฟังก์ชั่นซ็อกเก็ตน้อยมากต้องการให้ 8 ไบต์สุดท้ายของโครงสร้างที่อยู่ซ็อกเก็ตอินเทอร์เน็ตถูกตั้งค่าเป็น 0 อย่างไรก็ตามมันเป็นข้อผิดพลาดและอีกอันที่สามารถหลีกเลี่ยงได้โดยใช้ bzeroเพราะการแลกเปลี่ยนสองข้อโต้แย้งที่bzeroจะถูกจับโดยคอมไพเลอร์ C เสมอถ้าใช้ฟังก์ชั่นต้นแบบ

ฉันเชื่อว่าส่วนใหญ่ของการโทรไปmemset()ยังหน่วยความจำเป็นศูนย์ดังนั้นทำไมไม่ใช้ API ที่เหมาะกับกรณีการใช้งานที่?

ข้อเสียเปรียบที่เป็นไปได้bzero()คือคอมไพเลอร์อาจมีแนวโน้มที่จะปรับให้เหมาะสมที่สุดmemcpy()เพราะเป็นมาตรฐานและอาจถูกเขียนขึ้นเพื่อให้จดจำได้ อย่างไรก็ตามโปรดทราบว่ารหัสที่ถูกต้องนั้นยังดีกว่ารหัสที่ไม่ถูกต้องซึ่งได้รับการปรับปรุง ในกรณีส่วนใหญ่ที่ใช้bzero()จะไม่ทำให้เกิดผลกระทบที่เห็นได้ชัดกับประสิทธิภาพการทำงานของโปรแกรมและนั่นอาจจะเป็นแมโครหรือฟังก์ชั่นแบบอินไลน์ที่ขยายเพื่อbzero()memcpy()


ใช่ฉันคิดว่านี่อาจเป็นเหตุผลเมื่อทำงานในห้องเรียนเช่นนี้เพื่อทำให้นักเรียนสับสนน้อยลง ฉันไม่คิดว่านี่เป็นกรณีของอาจารย์ของฉัน เขาเป็นครู RTFM ที่ใหญ่มาก หากคุณมีคำถามที่สามารถตอบได้ในคู่มือเขาจะดึงหน้าคนบนโปรเจ็กเตอร์ในชั้นเรียนและแสดงให้คุณเห็น เขาเป็นอย่างมากเกี่ยวกับการคิดในใจของทุกคนว่ามีคู่มือให้อ่านและตอบคำถามส่วนใหญ่ของคุณ ฉันขอบคุณสำหรับสิ่งนี้เมื่อเทียบกับอาจารย์คนอื่น ๆ
PseudoPsyche

5
ฉันคิดว่านี่เป็นข้อโต้แย้งที่สามารถทำได้แม้นอกห้องเรียน - ฉันเห็นข้อบกพร่องนี้ในรหัสการผลิต มันทำให้ฉันรู้สึกผิดที่ทำง่าย ฉันเดาด้วยว่าการmemset()โทรส่วนใหญ่นั้นใช้เพื่อบล็อกศูนย์ความจำซึ่งฉันคิดว่าเป็นข้อโต้แย้งอีกข้อbzero()หนึ่ง อะไรคือ 'b' ที่bzero()ยืนหยัดอยู่ดี
Michael Burr

7
+1 ที่memsetละเมิดการเรียงลำดับพารามิเตอร์ทั่วไปของ "buffer, buffer_size" ทำให้มันผิดพลาดโดยเฉพาะอย่างยิ่ง IMO
jamesdlin

ในปาสคาลพวกเขาหลีกเลี่ยงสิ่งนั้นด้วยการเรียกมันว่า "fillchar" และต้องใช้ถ่าน คอมไพเลอร์ C / C ++ ส่วนใหญ่จะเลือกอันนั้น ซึ่งทำให้ฉันสงสัยว่าทำไมคอมไพเลอร์ไม่พูดว่า "คุณผ่านตัวชี้ 32/64 บิตที่คาดว่าไบต์" และเตะคุณอย่างมั่นคงในข้อผิดพลาดของคอมไพเลอร์
Móż

1
@ อาร์กิวเมนต์ที่สองและข้อที่สามอยู่ในลำดับที่ไม่ถูกต้อง การเรียกฟังก์ชั่นที่ยกมาไม่ได้ทำอะไรเลย
Ichthyo

4

ต้องการพูดถึงบางสิ่งเกี่ยวกับอาร์กิวเมนต์ bzero กับ memset ติดตั้ง ltrace แล้วเปรียบเทียบสิ่งที่ทำภายใต้ประทุน บน Linux ที่มี libc6 (2.19-0ubuntu6.6) การโทรออกจะเหมือนกันทุกประการ (ผ่านltrace ./test123):

long m[] = {0}; // generates a call to memset(0x7fffefa28238, '\0', 8)
int* p;
bzero(&p, 4);   // generates a call to memset(0x7fffefa28230, '\0', 4)

ฉันได้รับแจ้งว่าถ้าฉันไม่ทำงานในlibcหรือส่วนต่อประสานเคอร์เนล / syscall ใด ๆ ฉันไม่ต้องกังวลเกี่ยวกับสิ่งเหล่านั้น ทั้งหมดที่ฉันควรกังวลคือโทรตอบสนองความต้องการของ zero'ing บัฟเฟอร์ คนอื่นพูดถึงว่าอันไหนดีกว่ากันฉันจะหยุดที่นี่


สิ่งนี้เกิดขึ้นเพราะ GCC บางรุ่นจะปล่อยรหัส memset(ptr, 0, n)เมื่อพวกเขาเห็นbzero(ptr, n)และไม่สามารถแปลงเป็นรหัสแบบอินไลน์ได้
zwol

@zwol จริงๆแล้วมันเป็นมาโคร
SS Anne

1
@SSAnne gcc 9.3 บนคอมพิวเตอร์ของฉันทำการเปลี่ยนแปลงนี้เองโดยไม่ได้รับความช่วยเหลือจากมาโครในส่วนหัวของระบบ ก่อให้โทรไปextern void bzero(void *, size_t); void clear(void *p, size_t n) { bzero(p, n); } memset(รวมถึงstddef.hหากsize_tไม่มีสิ่งอื่นใดที่สามารถแทรกแซงได้)
zwol

4

คุณอาจไม่ควรใช้bzeroมันไม่ได้มาตรฐานจริง ๆ มันเป็นสิ่งที่ POSIX

และโปรดทราบว่าคำว่า "คือ" - ถูกคัดค้านใน POSIX.1-2001 และถูกลบใน POSIX.1-2008 เพื่อเป็นการระลึกถึง memset ดังนั้นคุณจึงควรใช้ฟังก์ชัน C มาตรฐานแทน


คุณหมายถึงอะไรโดยมาตรฐาน C? คุณหมายถึงไม่พบในไลบรารี C มาตรฐานใช่หรือไม่
Koray Tugay

@Koray มาตรฐาน C หมายถึงมาตรฐาน ISO และใช่bzeroไม่ใช่ส่วนหนึ่งของสิ่งนั้น
paxdiablo

ไม่ฉันหมายถึงฉันไม่ทราบว่าคุณหมายถึงมาตรฐานใด มาตรฐาน ISO หมายถึงไลบรารี C มาตรฐานหรือไม่ ที่มาพร้อมกับภาษา? ห้องสมุดน้อยที่สุดที่เรารู้ว่ามันจะอยู่ที่นั่น?
Koray Tugay

2
@Koray, ISO เป็นองค์กรมาตรฐานที่รับผิดชอบมาตรฐาน C, ปัจจุบันคือ C11 และ C99 และ C89 ก่อนหน้านี้ พวกเขาวางกฎที่การดำเนินการจะต้องปฏิบัติตามเพื่อพิจารณา C ดังนั้นใช่ถ้ามาตรฐานแจ้งว่าการนำไปปฏิบัติต้องจัดให้มี memset จะมีให้คุณ มิฉะนั้นจะไม่ใช่ C.
paxdiablo

2

สำหรับฟังก์ชั่น memset, อาร์กิวเมนต์ที่สองเป็นintและอาร์กิวเมนต์ที่สามคือsize_t,

void *memset(void *s, int c, size_t n);

ซึ่งโดยทั่วไปจะเป็นunsigned intแต่ถ้าค่าที่ต้องการ0 and 16สำหรับอาร์กิวเมนต์ที่สองและสามตามลำดับจะถูกป้อนในลำดับที่ไม่ถูกต้องเป็น 16 และ 0 จากนั้นการเรียกใช้เพื่อ memset ดังกล่าวยังคงสามารถทำงานได้ แต่จะไม่ทำอะไรเลย 0เพราะจำนวนไบต์ในการเริ่มต้นมีการระบุว่าเป็น

void bzero(void *s, size_t n)

ข้อผิดพลาดดังกล่าวสามารถหลีกเลี่ยงได้โดยใช้ bzero เนื่องจากการแลกเปลี่ยนสองอาร์กิวเมนต์ไปยัง bzero จะถูกคอมไพล์เลอร์ C เสมอหากใช้ฟังก์ชันต้นแบบ


1
ข้อผิดพลาดดังกล่าวสามารถหลีกเลี่ยงได้ด้วย memset หากคุณคิดว่าการโทรเป็น "ตั้งค่าหน่วยความจำนี้เป็นค่านี้สำหรับขนาดนี้" หรือถ้าคุณมี IDE ที่ให้ต้นแบบแก่คุณหรือแม้ว่าคุณเพิ่งรู้ว่าคุณเป็นใคร กำลังทำ :-)
paxdiablo

เห็นด้วย แต่ฟังก์ชั่นนี้ถูกสร้างขึ้นในเวลาที่ IDEs อัจฉริยะดังกล่าวไม่สามารถใช้ได้สำหรับการสนับสนุน
havish

2

ในระยะสั้น: จำเป็นต้องมีการดำเนินการชุมนุมมากขึ้นแล้วmemsetbzero

นี่คือแหล่งที่มา: http://fdiv.net/2009/01/14/memset-vs-bzero-ultimate-showdown


ใช่นั่นเป็นสิ่งหนึ่งที่ฉันพูดถึงใน OP จริงๆแล้วฉันยังเชื่อมโยงไปยังหน้าแน่นอน ปรากฎว่าดูเหมือนจะไม่ได้สร้างความแตกต่างมากนักเนื่องจากการปรับแต่งคอมไพเลอร์ สำหรับรายละเอียดเพิ่มเติมดูคำตอบที่ยอมรับโดย ouah
PseudoPsyche

6
นี่เป็นเพียงการแสดงให้เห็นว่าการดำเนินการ memset ขยะอย่างใดอย่างหนึ่งช้า บน MacOS X และระบบอื่น ๆ memset ใช้รหัสที่ตั้งค่า ณ เวลาบูตขึ้นอยู่กับโปรเซสเซอร์ที่คุณใช้ใช้การลงทะเบียนเวกเตอร์ทั้งหมดและสำหรับขนาดใหญ่ใช้คำแนะนำ prefetch ด้วยวิธีที่ชาญฉลาดเพื่อรับบิตสุดท้าย ของความเร็ว
gnasher729

คำแนะนำที่น้อยลงไม่ได้หมายถึงการดำเนินการที่รวดเร็วขึ้น ในความเป็นจริงการเพิ่มประสิทธิภาพมักจะเพิ่มขนาดไบนารีและจำนวนคำแนะนำเนื่องจากคลี่วงฟังก์ชั่นอินไลน์การจัดตำแหน่งห่วง ... ดูที่รหัสที่ดีที่สุดใด ๆ ที่ดีและคุณจะเห็นว่ามันมักจะมีคำแนะนำอะไรมากไปกว่าการใช้งานห่วย
phuclv

2

มีวิธีที่คุณชอบ :-)

#ifndef bzero
#define bzero(d,n) memset((d),0,(n))
#endif

โปรดทราบว่า:

  1. ต้นฉบับbzeroจะไม่ส่งคืนสิ่งใดmemsetส่งคืนโมฆะตัวชี้ ( d) สามารถแก้ไขได้โดยเพิ่ม typecast ให้เป็นโมฆะในคำจำกัดความ
  2. #ifndef bzeroไม่ได้ป้องกันไม่ให้คุณซ่อนฟังก์ชันดั้งเดิมแม้ว่าจะมีอยู่ก็ตาม มันทดสอบการมีอยู่ของแมโคร นี่อาจทำให้เกิดความสับสนมากมาย
  3. เป็นไปไม่ได้ที่จะสร้างตัวชี้ฟังก์ชันให้กับแมโคร เมื่อใช้งานbzeroผ่านตัวชี้ฟังก์ชั่นสิ่งนี้จะไม่ทำงาน

1
@Leeor มีปัญหาอะไร ความเกลียดชังทั่วไปสำหรับมาโคร? หรือคุณไม่ชอบความจริงที่ว่าแมโครนี้อาจสับสนกับฟังก์ชัน (และอาจซ่อนอยู่)
Palec

1
@Palec, หลัง การซ่อนนิยามใหม่ในฐานะมาโครอาจทำให้เกิดความสับสนได้ โปรแกรมเมอร์อีกคนที่ใช้รหัสนี้คิดว่าเขากำลังใช้สิ่งหนึ่งอยู่และถูกบังคับให้ใช้สิ่งอื่นโดยไม่รู้ตัว นั่นเป็นระเบิดเวลา
Leeor

1
หลังจากให้ความคิดอื่นฉันยอมรับว่านี่เป็นทางออกที่ไม่ดี เหนือสิ่งอื่นใดฉันพบเหตุผลทางเทคนิค: เมื่อใช้งานbzeroผ่านตัวชี้ฟังก์ชั่นสิ่งนี้จะไม่ทำงาน
Palec

จริงๆคุณควรจะได้บางสิ่งบางอย่างที่เรียกว่าแมโครของคุณอื่น ๆ bzeroกว่า นี่คือความโหดร้าย
Dan Bechard

-2

memset ใช้ 3 พารามิเตอร์, bzero ใช้ 2 ในหน่วยความจำที่ จำกัด ว่าพารามิเตอร์พิเศษจะใช้เวลา 4 ไบต์ขึ้นไปและส่วนใหญ่จะใช้เพื่อตั้งค่าทุกอย่างเป็น 0

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.