คำถามติดแท็ก c

C เป็นภาษาโปรแกรมทั่วไปที่ใช้สำหรับการเขียนโปรแกรมระบบ (ระบบปฏิบัติการและฝังตัว), ห้องสมุด, เกมและข้ามแพลตฟอร์ม แท็กนี้ควรใช้กับคำถามทั่วไปที่เกี่ยวข้องกับภาษา C ตามที่กำหนดไว้ในมาตรฐาน ISO 9899 (เวอร์ชันล่าสุด 9899: 2018 เว้นแต่ระบุไว้เป็นอย่างอื่น - นอกจากนี้ยังติดแท็กคำขอเฉพาะรุ่นด้วย c89, c99, c11 ฯลฯ ) C แตกต่างจาก C ++ และไม่ควรใช้ร่วมกับแท็ก C ++ หากไม่มีเหตุผล

4
มีข้อมูลโค้ด C ที่คำนวณการเพิ่มความปลอดภัยมากเกินไปอย่างมีประสิทธิภาพโดยไม่ใช้คอมไพเลอร์ builtins หรือไม่
นี่คือฟังก์ชั่น C ที่เพิ่มintอีกอันหนึ่งซึ่งล้มเหลวหากเกิดโอเวอร์โฟลว์: int safe_add(int *value, int delta) { if (*value >= 0) { if (delta > INT_MAX - *value) { return -1; } } else { if (delta < INT_MIN - *value) { return -1; } } *value += delta; return 0; } น่าเสียดายที่GCC หรือ Clang นั้นไม่ได้รับการปรับปรุงอย่างดี : safe_add(int*, …

1
การติดตั้งวงเล็บมุมของ GCC รวมถึง ทำไมต้องอธิบายตามด้านล่าง?
เอกสารนี้ในส่วนที่2.6 คำนวณรวมมีย่อหน้าต่อไปนี้: หากบรรทัดนั้นขยายไปยังสตรีมโทเค็นที่เริ่มต้นด้วย <โทเค็นและรวมถึงโทเค็น> โทเค็นที่อยู่ระหว่าง <และตัวแรก> จะรวมกันเพื่อสร้างชื่อไฟล์ที่จะรวม ช่องว่างใด ๆ ระหว่างโทเค็นจะถูกลดขนาดเป็นช่องว่างเดียว แล้วพื้นที่ใด ๆ หลังจากที่เริ่มต้น <จะถูกเก็บไว้ แต่พื้นที่ต่อท้ายก่อนปิด> ถูกละเว้น CPP ค้นหาไฟล์ตามกฎสำหรับการรวมวงเล็บมุม ฉันรู้ว่านี่เป็นการกำหนดการนำไปใช้ แต่ทำไมต้องเป็นเช่นนี้สำหรับ GCC ฉันหมายถึงเฉพาะประโยคที่เน้นสีด้านบน แก้ไข ฉันเพิ่งสังเกตเห็นว่าย่อหน้าที่สามก่อนที่จะยกมาข้างต้นกล่าวว่าต่อไปนี้: คุณต้องระวังเมื่อคุณกำหนดแมโคร #defineบันทึกโทเค็นไม่ใช่ข้อความ ตัวประมวลผลล่วงหน้าไม่มีทางรู้ได้ว่าแมโครจะถูกใช้เป็นอาร์กิวเมนต์#includeดังนั้นจึงสร้างโทเค็นสามัญไม่ใช่ชื่อส่วนหัว สิ่งนี้ไม่น่าจะทำให้เกิดปัญหาหากคุณใช้เครื่องหมายคำพูดคู่ซึ่งรวมถึงค่าคงที่ของสตริง ถ้าคุณใช้วงเล็บมุม แต่คุณอาจมีปัญหา ไม่มีใครรู้ว่าปัญหาแบบไหนที่ชี้ให้เห็นที่นี่?
11 c++  c  gcc  language-lawyer 

3
การคืนค่าตัวชี้โมฆะที่ไม่ซ้ำใครจากฟังก์ชั่น
ในการรับvoid *ฟังก์ชั่นใน CI จะทำสิ่งนี้ (ตัวอย่างพื้นฐานมาก): void *get_ptr(size_t size) { void *ptr = malloc(size); return ptr; } ฉันจะได้ผลลัพธ์เดียวกันเมื่อใช้งานได้std::unique_ptr<>อย่างไร
11 c++  c  unique-ptr 

2
โค้ดตัวอย่างของ IBM ฟังก์ชั่นที่ไม่ใช่ผู้เข้าร่วมใหม่ไม่ทำงานในระบบของฉัน
ฉันกำลังศึกษาเรื่องการเขียนโปรแกรมอีกครั้ง บนเว็บไซต์ของ IBM (อันนี้ดีจริงๆ) ฉันได้ก่อตั้งรหัสแล้วคัดลอกด้านล่าง มันเป็นรหัสแรกที่นำมาลงเว็บไซต์ รหัสพยายามแสดงปัญหาที่เกี่ยวข้องกับการเข้าถึงตัวแปรในการพัฒนาเชิงเส้นของโปรแกรมข้อความ (asynchronicity) โดยการพิมพ์ค่าสองค่าที่เปลี่ยนแปลงตลอดเวลาใน "บริบทอันตราย" #include <signal.h> #include <stdio.h> struct two_int { int a, b; } data; void signal_handler(int signum){ printf ("%d, %d\n", data.a, data.b); alarm (1); } int main (void){ static struct two_int zeros = { 0, 0 }, ones = { 1, 1 …
11 c  gcc  signals  x86-64  data-race 

1
ทำไมคอมไพเลอร์ยืนยันที่จะใช้การลงทะเบียนที่บันทึกไว้ที่นี่?
พิจารณารหัส C นี้: void foo(void); long bar(long x) { foo(); return x; } เมื่อฉันรวบรวมใน GCC 9.3 ด้วย-O3หรือ-Osฉันได้รับ: bar: push r12 mov r12, rdi call foo mov rax, r12 pop r12 ret เอาท์พุทจากเสียงดังกราวเหมือนกันยกเว้นการเลือกrbxแทนr12การลงทะเบียน callee- บันทึก อย่างไรก็ตามฉันต้องการ / คาดหวังว่าจะเห็นชุดประกอบที่มีลักษณะดังนี้: bar: push rdi call foo pop rax ret ในภาษาอังกฤษนี่คือสิ่งที่ฉันเห็นว่าเกิดขึ้น: ผลักดันค่าเก่าของการลงทะเบียนที่บันทึกไว้แบบสลี ย้ายxไปยังการลงทะเบียนที่ถูกบันทึกด้วย callee โทร …
10 c  gcc  assembly  clang  x86-64 

3
การตัดทอนเลขจำนวนเต็มบิทฟิลด์ที่ไม่ได้ลงนามระหว่าง C ++ และ C ที่ไม่สอดคล้องกันในคอมไพเลอร์ต่างกัน
แก้ไข 2 : ฉันแก้ไขข้อผิดพลาดในการทดสอบที่ผิดปกติเมื่อฟังก์ชั่นก่อนหน้านี้อาศัยอยู่ในไฟล์ต้นฉบับ C ++ แต่ย้ายไปเป็นคำต่อคำของไฟล์ C เริ่มส่งคืนผลลัพธ์ที่ไม่ถูกต้อง MVE ด้านล่างอนุญาตให้สร้างปัญหาขึ้นอีกครั้งด้วย GCC อย่างไรก็ตามเมื่อฉันตั้งใจรวบรวมตัวอย่างกับ Clang (และต่อมากับ VS) ฉันได้ผลลัพธ์ที่ต่างออกไป! ฉันไม่สามารถคิดได้ว่าจะจัดการสิ่งนี้เป็นข้อบกพร่องในคอมไพเลอร์ตัวใดตัวหนึ่งหรือเป็นการรวมตัวของผลลัพธ์ที่ไม่ได้กำหนดซึ่งอนุญาตโดยมาตรฐาน C หรือ C ++ แปลกไม่มีคอมไพเลอร์ให้คำเตือนใด ๆ เกี่ยวกับการแสดงออก ผู้ร้ายคือการแสดงออกนี้: ctl.b.p52 << 12; ที่นี่p52พิมพ์เป็นuint64_t; มันยังเป็นส่วนหนึ่งของสหภาพ (ดูcontrol_tด้านล่าง) การดำเนินการกะจะไม่สูญเสียข้อมูลใด ๆ เนื่องจากผลลัพธ์ยังพอดีกับ 64 บิต อย่างไรก็ตาม GCC ตัดสินใจตัดทอนผลลัพธ์เป็น 52 บิตหากฉันใช้คอมไพเลอร์ C ! ด้วยคอมไพเลอร์ C ++ ผลลัพธ์ 64 บิตทั้งหมดจะถูกเก็บไว้ …

1
ตั้งค่าถ่านเป็น CHAR_MAX รับประกันว่าจะพันไปที่ CHAR_MIN หรือไม่?
รหัสของฉัน: #include <stdio.h> #include <limits.h> int main() { char c = CHAR_MAX; c += 1; printf("CHAR_MIN=%d CHAR_MAX=%d c=%d (%c)\n", CHAR_MIN, CHAR_MAX, c, c); } เอาท์พุท: CHAR_MIN=-128 CHAR_MAX=127 c=-128 () เราจะเห็นว่าเมื่อเราเพิ่มcharชุดตัวแปรก็ล้อมรอบไปCHAR_MAX CHAR_MINพฤติกรรมนี้รับประกันหรือไม่ หรือมันจะเป็นพฤติกรรมที่ไม่ได้กำหนดหรือพฤติกรรมที่ระบุการใช้งาน? มาตรฐาน C99 พูดถึงอะไรเกี่ยวกับเรื่องนี้ [หมายเหตุ: จะเกิดอะไรขึ้นเมื่อให้ค่าที่มากกว่า CHAR_MAX (127) ถึงถ่านหรือC- ทำไมถ่าน c = 129 จะเปลี่ยนเป็น -127 ไม่ตอบคำถามนี้เพราะพวกเขาพูดถึงการกำหนดค่านอกช่วงไม่เพิ่มมูลค่าให้กับค่านอกช่วง]


1
C11 Atomic Acquire / Release และ x86_64 ขาดการเชื่อมโยงโหลด / จัดเก็บ?
ฉันกำลังดิ้นรนกับมาตรา 5.1.2.4 ของมาตรฐาน C11 โดยเฉพาะความหมายของการเปิดตัว / การได้มา ฉันทราบว่าhttps://preshing.com/20120913/acquire-and-release-semantics/ (ในจำนวนอื่น ๆ ) ระบุว่า: ... ความหมายของการวางจำหน่ายป้องกันการเรียงลำดับหน่วยความจำของการปล่อยการเขียนด้วยการดำเนินการอ่านหรือการเขียนที่นำหน้ามันตามลำดับของโปรแกรม ดังนั้นสำหรับต่อไปนี้: typedef struct test_struct { _Atomic(bool) ready ; int v1 ; int v2 ; } test_struct_t ; extern void test_init(test_struct_t* ts, int v1, int v2) { ts->v1 = v1 ; ts->v2 = v2 ; atomic_store_explicit(&ts->ready, false, …

4
ทำไมส่งคืน NULL จาก main ()
บางครั้งฉันเห็นโคเดอร์ที่ใช้NULLเป็นค่าส่งคืนของmain()ในโปรแกรม C และ C ++ ตัวอย่างเช่น: #include <stdio.h> int main() { printf("HelloWorld!"); return NULL; } เมื่อฉันรวบรวมรหัส `นี้กับ gcc ฉันได้รับคำเตือน: คำเตือน: return ทำให้จำนวนเต็มจากตัวชี้โดยไม่ต้องส่ง [-Wint-conversion] ซึ่งมีความสมเหตุสมผลเนื่องจากแมโครNULLจะถูกขยายไปและค่าตอบแทนของหลักจะเป็นประเภท(void*) 0int เมื่อฉันสร้างโปรแกรม C ++ สั้น ๆ ของ: #include <iostream> using namespace std; int main() { cout << "HelloWorld!"; return NULL; } และคอมไพล์ด้วย g ++ ฉันจะได้รับคำเตือนที่เทียบเท่า: คำเตือน: …
10 c++  c  null  return  return-value 

2
prefetcher L2 HW มีประโยชน์จริง ๆ หรือไม่
ฉันอยู่ที่Whisky Lake i7-8565Uและวิเคราะห์เคาน์เตอร์ที่สมบูรณ์แบบและเวลาสำหรับการคัดลอกข้อมูลขนาด 512 KiB (ขนาดแคช L2 มากกว่าสองเท่า) และต้องเผชิญกับความเข้าใจผิดบางประการเกี่ยวกับการทำงานของ L2 HW prefetcher ในIntel Manual Vol.4 MSRมี MSR 0x1A4บิต 0 เป็นสำหรับการควบคุมการใช้ prefetcher L2 HW (1 เพื่อปิดการใช้งาน) พิจารณาเกณฑ์มาตรฐานดังต่อไปนี้: memcopy.h: void *avx_memcpy_forward_lsls(void *restrict, const void *restrict, size_t); memcopy.S: avx_memcpy_forward_lsls: shr rdx, 0x3 xor rcx, rcx avx_memcpy_forward_loop_lsls: vmovdqa ymm0, [rsi + 8*rcx] vmovdqa [rdi …

1
MATLAB ไม่ยกเลิกการโหลดไฟล์ MEX หลังจากอัปเกรดเป็น macOS Mojave
ใน MATLAB ให้clear mexยกเลิกการโหลดไฟล์ MEX ทั้งหมดจากหน่วยความจำ (เว้นแต่ว่าพวกเขาจะถูกล็อค) ภายใต้ macOS เวอร์ชันก่อนหน้าฉันสามารถคอมไพล์ไฟล์ MEX อีกครั้งและรันเวอร์ชันที่แก้ไขโดยไม่ต้องรีสตาร์ท MATLAB เพียงแค่ออกclear mexคำสั่ง สิ่งนี้ไม่สามารถทำได้ใน Mojave อีกต่อไป ตัวอย่างเช่นใช้ไฟล์ MEX เล็กน้อย ( get_data_pointer.c): #include "mex.h" void mexFunction( int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) { plhs[0] = mxCreateNumericMatrix(1, 1, mxUINT64_CLASS, mxREAL); *(uint64_t*)mxGetData(plhs[0]) = (uint64_t)mxGetData(prhs[0]); } เราสามารถสร้างไฟล์ MEX …

5
การเชื่อมโยงแบบไดนามิก - Vs Linux ของ windows
ใน Windows เมื่อฉันรวบรวมรหัส C / C ++ ในโครงการ DLL ใน MSVC ฉันได้รับ 2 ไฟล์: MyDll.dll MyDll.lib ที่เท่าที่ฉันเข้าใจMyDll.libมีชนิดของตารางตัวชี้ที่ระบุตำแหน่งฟังก์ชั่นใน dll เมื่อใช้ dll นี้พูดในไฟล์ exe MyDll.libจะถูกฝังลงในไฟล์ exe ในระหว่างการเชื่อมโยงดังนั้นในขณะรันไทม์มัน "รู้" ซึ่งฟังก์ชั่นตั้งอยู่ในMyDll.dllและสามารถใช้งานได้ แต่ถ้าฉันรวบรวมรหัสเดียวกันภายใต้ Linux ฉันได้รับเพียงไฟล์เดียวMySo.soโดยไม่ MySo.a(เทียบเท่ากับlibไฟล์ใน Linux) ดังนั้นไฟล์ปฏิบัติการภายใต้ Linux รู้ได้อย่างไรว่าฟังก์ชั่นตั้งอยู่ที่ไหนMySo.soถ้าไม่มีอะไรฝังอยู่ในระหว่างการเชื่อมโยง?

4
อักขระอาร์เรย์ควรใช้เป็นสตริงอย่างไร
ฉันเข้าใจว่าสตริงใน C เป็นเพียงอาร์เรย์อักขระ ดังนั้นฉันลองรหัสต่อไปนี้ แต่ให้ผลลัพธ์ที่แปลกประหลาดเช่นผลลัพธ์ขยะหรือโปรแกรมขัดข้อง: #include <stdio.h> int main (void) { char str [5] = "hello"; puts(str); } ทำไมมันไม่ทำงาน gcc -std=c17 -pedantic-errors -Wall -Wextraมันรวบรวมหมดจดด้วย หมายเหตุ:โพสต์นี้มีวัตถุประสงค์เพื่อใช้เป็นคำถามที่พบบ่อยซึ่งเป็นที่ยอมรับสำหรับปัญหาที่เกิดจากความล้มเหลวในการจัดสรรห้องสำหรับเทอร์มินัล NUL เมื่อประกาศสตริง

2
วิธีการตรวจสอบว่าเป็นโมฆะตัวชี้ (void *) เป็นหนึ่งในสองชนิดข้อมูล?
ฉันกำลังเขียนฟังก์ชันที่ฉันต้องการยอมรับtypeพารามิเตอร์2 วินาที A string(อักขระ *) structureที่จะมี n จำนวนขององค์ประกอบ และเพื่อให้บรรลุนี้ฉันคิดว่าใช้ง่ายvoid *เป็นพารามิเตอร์ประเภท แต่ฉันไม่ทราบวิธีการตรวจสอบว่าพารามิเตอร์เป็นประเภทหนึ่งหรืออื่น ๆ อย่างปลอดภัย
10 c  gcc  types  clang 

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