gpt4 book ai didi

c - 如何检测代码意外创建指向指针的指针的实例?

转载 作者:行者123 更新时间:2023-11-30 18:36:57 24 4
gpt4 key购买 nike

在进行一些大规模重构时,我遇到过犯同样错误的情况。我不小心将指针传递给了指针,而不仅仅是指针。

代码解释得最好。查找下面的 /* oops */

结构:

struct my_struct {
int x;
int y;
int z;
int value;
}

初始化函数:

void initialize(struct my_struct *s)
{
s->x = 0;
s->y = 0;
s->z = 0;
s->value = 0;
}

原函数:

struct my_struct do_something()
{
struct my_struct s;

initialize(&s);

s.value = 27;

return s;
}

新功能

void do_something(struct my_struct *s)
{
initialize(&s); /* oops! */

s->value = 27;
}

应该是:

void do_something(struct my_struct *s)
{
initialize(s); /* fixed */

s->value = 27;
}

有没有办法,也许是编译器标志或 linter 可以帮助我找到这些问题?

注释:我正在使用 gcc(但如果其他编译器或 linter 可以找到它,请告诉)

我正在使用这些编译器标志,但它们没有捕获它:

CFLAGS = \
-std=c89 \
-pedantic \
-pedantic-errors \
-Werror \
-Wextra \
-Wmissing-prototypes \
-Wall \
-Wold-style-definition \
-Wdeclaration-after-statement \
-Wundef \
-Wpointer-arith \
-Wcast-qual \
-Wcast-align \
-Wfloat-equal \
-Wno-missing-braces

我在所有内容的标题中都有原型(prototype)。

这不是我选择的标准——C90。 C99和C11也都接受。

$ gcc --version
gcc (GCC) 6.1.1 20160621 (Red Hat 6.1.1-3)

最佳答案

将指针传递给仅需要指针的指针必定会导致编译器错误。因此我无法重现您的示例所建议的内容(GCC 5.4.0,C99)。

但是有一种情况会导致这种错误:

foo.h:

struct foo {
int dummy;
};

main.c:

#include "foo.h"
void init(void *);
int main() {
struct foo f;
struct foo * fp = &f;
init(&f);
init(&fp);
return 0;
}

init.c:

#include "foo.h"
// Need a prototype because otherwise -Wmissing-prototypes issues a warning
// Such code is not that uncommon, though, especially when e.g. there
// are C preprocessor macros that help defining some kinds of functions.
void init(struct foo *f);
void init(struct foo *f) {
f->dummy = 42;
}

编译正常,没有任何警告。翻译单元 main.c 看到(错误的)声明 void init(void *) ,因此在传递不同的指针类型时不会发出警告(因为它们都是隐式可转换的)到void *)。由于 C 编译器通常不会将参数类型修改为生成的目标文件的符号,因此链接器会很乐意使用以下命令解析来自 main.o 的函数 init 的引用: init.o 中的函数符号 init

[nix-shell:/tmp/wtf]$ nm init.o 
0000000000000000 T init
[nix-shell:/tmp/wtf]$ nm main.o
U _GLOBAL_OFFSET_TABLE_
U init
0000000000000000 T main
U __stack_chk_fail

C++ 编译器确实将参数类型转换为符号,因此:

[nix-shell:/tmp/wtf]$ LANG= g++ -Wall -Wextra main.c init.c 
/run/user/1000/cctWt0Nl.o: In function `main':
main.c:(.text.startup+0x1d): undefined reference to `init(void*)'
main.c:(.text.startup+0x27): undefined reference to `init(void*)'
collect2: error: ld returned 1 exit status

注意:我建议使用 C++ 编译器编译 C 代码。请不要这样做。

关于c - 如何检测代码意外创建指向指针的指针的实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39373918/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com