我目前正在开发一个项目,包括使用void指针的一些通用链表实现。为这些列表提供了一些非常好的函数,我决定只使用元素的识别函数(const void *)。 在添加const关键字之后是必要的,我想到了我的代码现在是多么正确(如果我实现了之前的所有内容)。
由于编译器(GCC)没有警告我,我决定接受测试。 我使用" gcc -g -Wall test.c"编译了以下代码。海湾合作委员会没有收到任何警告。
#include <stdio.h>
#include <stdlib.h>
void testf(const void *testp){
*((int32_t *) testp) += 1;
}
void testf2(const int32_t *testp){
*((int32_t *) testp) += 1;
}
int main(){
int32_t testv = 0;
printf("%i \n", testv);
testf(&testv);
printf("%i \n", testv);
testf2(&testv);
printf("%i \n", testv);
return 0;
}
输出如下:
0
1
2
我没想到C会因此而崩溃,但我希望编译器收到警告。在这个例子中,我只是在我的实际函数中进行转换,我还将const void指针分配给tmp变量。
这是一个错误吗?
鉴于今天的编译器有多复杂,Id至少会发出一个警告,即我正在向非const指针投射指针。如果我更改了强制转换并在那里添加了const关键字,GCC会抛出我尝试分配给只读位置的常见错误
我是否应该重新考虑我对表示const指针的函数的信任?这不是我作为合同所理解的:)
答案 0 :(得分:5)
这是一个错误吗?
不,不是。通过投射你会对编译器说“我知道我在做什么”。
但GCC确实有一个选项-Wcast-qual
,如果一个限定符是故意丢弃的话,它会被捕获。
答案 1 :(得分:0)
我使用以下代码编译了发布的代码:
gcc -c -ggdb -Wall -Wextra -pedantic -std=c99 filename.c -o filename.o
(以下列表是为了便于阅读而缩写)
error: 'int32_t' undeclared
error: expected expression before ')' token
*((int32_t *) testp) += 1;
warning: unused parameter 'testp'
void testf(const void *testp){
有关int32_t
你的编译器肯定会说明这些相同的内容。
BTW:缺少的头文件是stdint.h
。