ฉันได้อ่านโพสต์ต่างๆ ในStack Overflow RE: ข้อผิดพลาดพอยน์เตอร์ที่พิมพ์ผิดประเภท ความเข้าใจของฉันคือข้อผิดพลาดโดยพื้นฐานแล้วคำเตือนของคอมไพเลอร์เกี่ยวกับอันตรายของการเข้าถึงวัตถุผ่านตัวชี้ประเภทอื่น (แม้ว่าจะมีข้อยกเว้นเกิดขึ้น) ซึ่งเป็นคำเตือนที่เข้าใจได้และสมเหตุสมผล char*
คำถามของฉันเฉพาะรหัสด้านล่าง: เหตุใดการกำหนดที่อยู่ของตัวชี้ให้มีvoid**
คุณสมบัติสำหรับคำเตือนนี้ (เลื่อนเป็นข้อผิดพลาดผ่าน-Werror
)
ยิ่งไปกว่านั้นโค้ดนี้ได้รับการรวบรวมสำหรับสถาปัตยกรรมเป้าหมายหลาย ๆ อันซึ่งหนึ่งในนั้นเท่านั้นที่สร้างคำเตือน / ข้อผิดพลาด - นี่อาจหมายถึงว่ามันเป็นข้อบกพร่องเฉพาะรุ่นคอมไพเลอร์อย่างถูกกฎหมายหรือไม่
// main.c
#include <stdlib.h>
typedef struct Foo
{
int i;
} Foo;
void freeFunc( void** obj )
{
if ( obj && * obj )
{
free( *obj );
*obj = NULL;
}
}
int main( int argc, char* argv[] )
{
Foo* f = calloc( 1, sizeof( Foo ) );
freeFunc( (void**)(&f) );
return 0;
}
หากความเข้าใจของฉันตามที่ระบุไว้ข้างต้นถูกต้อง a void**
ยังเป็นเพียงแค่ตัวชี้นี่ควรจะเป็นการคัดเลือกนักแสดงที่ปลอดภัย
มีวิธีแก้ปัญหาโดยไม่ใช้ lvaluesที่จะทำให้คำเตือน / ข้อผิดพลาดเฉพาะคอมไพเลอร์นี้สงบหรือไม่? คือฉันเข้าใจว่าและทำไมสิ่งนี้จะแก้ไขปัญหาได้ แต่ฉันต้องการหลีกเลี่ยงวิธีการนี้เพราะฉันต้องการใช้ประโยชน์จากfreeFunc()
NULLที่ตั้งใจจะหาเรื่อง:
void* tmp = f;
freeFunc( &tmp );
f = NULL;
ผู้รวบรวมปัญหา (หนึ่งในหนึ่ง):
user@8d63f499ed92:/build$ /usr/local/crosstool/x86-fc3/bin/i686-fc3-linux-gnu-gcc --version && /usr/local/crosstool/x86-fc3/bin/i686-fc3-linux-gnu-gcc -Wall -O2 -Werror ./main.c
i686-fc3-linux-gnu-gcc (GCC) 3.4.5
Copyright (C) 2004 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
./main.c: In function `main':
./main.c:21: warning: dereferencing type-punned pointer will break strict-aliasing rules
user@8d63f499ed92:/build$
คอมไพเลอร์ไม่บ่น (หนึ่งในหลาย ๆ ):
user@8d63f499ed92:/build$ /usr/local/crosstool/x86-rh73/bin/i686-rh73-linux-gnu-gcc --version && /usr/local/crosstool/x86-rh73/bin/i686-rh73-linux-gnu-gcc -Wall -O2 -Werror ./main.c
i686-rh73-linux-gnu-gcc (GCC) 3.2.3
Copyright (C) 2002 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
user@8d63f499ed92:/build$
อัปเดต: ฉันได้ค้นพบคำเตือนเพิ่มเติมจะปรากฏขึ้นเฉพาะเมื่อคอมไพล์ด้วย-O2
(ยังคงอยู่กับ "คอมไพเลอร์ปัญหา" เท่านั้น)
void**
ยังเป็นเพียงแค่ตัวชี้นี่ควรจะเป็นการคัดเลือกนักแสดงที่ปลอดภัย" ว้าวมี skippy! ดูเหมือนคุณจะมีข้อสมมติฐานพื้นฐานเกิดขึ้น พยายามคิดให้น้อยลงในแง่ของไบต์และคานและอื่น ๆ ในแง่ของ abstractions เพราะนั่นคือสิ่งที่คุณกำลังเขียนโปรแกรมด้วย