是否在 C 中实现了 void 安全?
Is void safety implemented in C?
根据Wikipedia,
Void safety is a guarantee within an object-oriented programming
language that no object references will have null or void values
这很好,但是 C 不是面向对象的 PL,该定义仅适用于空指针或对对象实例的引用的取消引用。
那么,C语言有没有void安全?这个词(或其反义词)甚至可以适用于描述语言吗?
没有。但是,如果您使用指针,C++(一种面向对象的编程语言)中也没有。 C++ references 是应该始终引用真实对象的东西,指针在 C 和 C++ 中都可以为 NULL。您也许可以 get C++ 中的悬挂引用,但是,作为未定义的行为,您违反了规则,所有赌注都被取消了。
C 本身没有 没有引用,只有指针,你根本得不到那种级别的保护,除非你自己手动做:
if (ptr != NULL)
doSomethingWith (*ptr);
在 C 中,代码如下:
char *xyzzy = NULL;
char plugh = *xyzzy;
只是找麻烦,但编译器不会阻止你这样做,因为它是完全合法的(尽管,对于 C++ 情况,未定义的行为)。
C 中没有 NULL 安全。C 中没有引用,只有指针。指针可以设置为 NULL,取消引用 NULL ptr 会导致分段错误,例如:
int main(int argc, char **argv) {
int val = 5555;
int val2 = 555;
int *ptr;
ptr = &val; /* ptr now points to the address of val */
printf("Address: 0x%.8x [0x%.8x]", &ptr, &val);
printf("\nAddress: 0x%.8x [0x%.8x]", ptr, &val);
printf("\nValue: %d [%d]", *ptr, val);
ptr = &val2;
printf("\n\n\nNew Address: 0x%.8x [0x%.8x]", &ptr, &val2);
printf("\nNew Address: 0x%.8x [0x%.8x]", ptr, &val2);
printf("\nNew Value: %d [%d]\n\n", *ptr, val2);
ptr = NULL;
printf("\nptr = %d", ptr);
printf("\n&ptr = 0x%.8x", &ptr);
// printf("\n*ptr = %d", *ptr); /* causes segfault */
return 0;
}
char@char:~$ ./a.out
地址:0xf8638e50 [0xf8638e5c]
地址:0xf8638e5c [0xf8638e5c]
值:5555 [5555]
新地址:0xf8638e50 [0xf8638e58]
新地址:0xf8638e58 [0xf8638e58]
新值:555 [555]
ptr = 0
&ptr = 0xf8638e50
但是如果您取消对最后一次调用 printf 的注释,您将得到:
char@char:~$ ./a.out
地址:0xfbb6cae0 [0xfbb6caec]
地址:0xfbb6caec [0xfbb6caec]
值:5555 [5555]
新地址:0xfbb6cae0 [0xfbb6cae8]
新地址:0xfbb6cae8 [0xfbb6cae8]
新值:555 [555]
ptr = 0
分段错误
当没有对象引用时(例如在 C 中),很容易保证没有对象引用具有 null 或 void 值。
说C有void安全是对的,但也是没有意义的。有关详细信息,请参阅:http://en.wikipedia.org/wiki/Vacuous_truth
根据Wikipedia,
Void safety is a guarantee within an object-oriented programming language that no object references will have null or void values
这很好,但是 C 不是面向对象的 PL,该定义仅适用于空指针或对对象实例的引用的取消引用。
那么,C语言有没有void安全?这个词(或其反义词)甚至可以适用于描述语言吗?
没有。但是,如果您使用指针,C++(一种面向对象的编程语言)中也没有。 C++ references 是应该始终引用真实对象的东西,指针在 C 和 C++ 中都可以为 NULL。您也许可以 get C++ 中的悬挂引用,但是,作为未定义的行为,您违反了规则,所有赌注都被取消了。
C 本身没有 没有引用,只有指针,你根本得不到那种级别的保护,除非你自己手动做:
if (ptr != NULL)
doSomethingWith (*ptr);
在 C 中,代码如下:
char *xyzzy = NULL;
char plugh = *xyzzy;
只是找麻烦,但编译器不会阻止你这样做,因为它是完全合法的(尽管,对于 C++ 情况,未定义的行为)。
C 中没有 NULL 安全。C 中没有引用,只有指针。指针可以设置为 NULL,取消引用 NULL ptr 会导致分段错误,例如:
int main(int argc, char **argv) {
int val = 5555;
int val2 = 555;
int *ptr;
ptr = &val; /* ptr now points to the address of val */
printf("Address: 0x%.8x [0x%.8x]", &ptr, &val);
printf("\nAddress: 0x%.8x [0x%.8x]", ptr, &val);
printf("\nValue: %d [%d]", *ptr, val);
ptr = &val2;
printf("\n\n\nNew Address: 0x%.8x [0x%.8x]", &ptr, &val2);
printf("\nNew Address: 0x%.8x [0x%.8x]", ptr, &val2);
printf("\nNew Value: %d [%d]\n\n", *ptr, val2);
ptr = NULL;
printf("\nptr = %d", ptr);
printf("\n&ptr = 0x%.8x", &ptr);
// printf("\n*ptr = %d", *ptr); /* causes segfault */
return 0;
}
char@char:~$ ./a.out
地址:0xf8638e50 [0xf8638e5c]
地址:0xf8638e5c [0xf8638e5c]
值:5555 [5555]
新地址:0xf8638e50 [0xf8638e58]
新地址:0xf8638e58 [0xf8638e58]
新值:555 [555]
ptr = 0
&ptr = 0xf8638e50
但是如果您取消对最后一次调用 printf 的注释,您将得到:
char@char:~$ ./a.out
地址:0xfbb6cae0 [0xfbb6caec]
地址:0xfbb6caec [0xfbb6caec]
值:5555 [5555]
新地址:0xfbb6cae0 [0xfbb6cae8]
新地址:0xfbb6cae8 [0xfbb6cae8]
新值:555 [555]
ptr = 0
分段错误
当没有对象引用时(例如在 C 中),很容易保证没有对象引用具有 null 或 void 值。
说C有void安全是对的,但也是没有意义的。有关详细信息,请参阅:http://en.wikipedia.org/wiki/Vacuous_truth