【发布时间】:2012-08-25 08:54:57
【问题描述】:
我正在修复一些代码的错误,编译器(合法地)警告说函数 dynscat() 没有被声明——其他人对可接受的编码标准的想法——所以我追踪了函数的定义位置(很容易)和哪个标头声明了它(无;Grrr!)。但我期待找到结构定义的细节对于qqparse_val 的extern 声明是必要的:
extern struct t_dynstr qqparse_val;
extern void dynscat(struct t_dynstr *s, char *p);
extern void qqcat(char *s);
void qqcat(char *s)
{
dynscat(&qqparse_val, s);
if (*s == ',')
dynscat(&qqparse_val, "$");
}
原代码中的qqcat()函数是静态的; extern 声明消除了代码的这个 sn-p 的编译器警告。 dynscat() 函数声明完全丢失;再次,添加它会消除警告。
通过显示的代码片段,很明显只使用了变量的地址,因此在某种程度上,结构的细节未知并不重要。如果变量extern struct t_dynstr *p_parseval;,你不会看到这个问题;这将是 100% 的预期。如果代码需要访问结构的内部,则需要结构定义。但我一直认为,如果你声明变量是一个结构(而不是指向结构的指针),编译器会想知道结构的大小——但显然不是。
我尝试过让 GCC 抱怨,但它没有,即使是 GCC 4.7.1:
gcc-4.7.1 -c -Wall -Wextra -std=c89 -pedantic surprise.c
该代码已经在 AIX、HP-UX、Solaris、Linux 上编译了十年,因此它不是特定于 GCC 的。
问题
C 标准是否允许这样做(主要是 C99 或 C11,但 C89 也可以)?哪个板块?还是我只是碰到了一个奇怪的案例,它可以在它移植到的所有机器上运行,但没有得到标准的正式认可?
【问题讨论】:
-
如果 dynstr.h 被定义在某个地方应该没问题,不是吗?
-
@Shark:代码正是显示的内容;不需要标题。
-
究竟有什么令人惊讶的?你可以获取类型不完整的对象的地址吗?
-
这个问题包含大量不必要的信息。我建议将其删减为基本要素,例如:“为什么 C 标准允许
extern struct foo;… /* Now inside a function. */ &foo,以及哪些部分提供了相关信息?”
标签: c