c - ANSI C 之前的结构选择器使用

标签 c pointers gcc struct ansi

几年前,在 C 标准化之前,允许在地址上使用结构选择器。例如,允许并经常使用以下代码。

#define PTR 0xAA000
struct {  int integ; };

func() {
   int i;
   i = PTR->integ;    /* here, c is set to the first int at PTR */
   return c;
}

也许它不是很整洁,但我喜欢它。在我看来,这种语言的强大功能和多功能性还取决于它没有约束。如今,编译器只是转储一个错误。我想知道是否可以在 GNU C 编译器中消除这种限制。

PS:C 的发明者在 UNIX 内核上使用了类似的代码。(在 V6 中,一些伪结构已在 param.h 中声明)

最佳答案

“几年前”实际上是很久很久以前。 AFAICR,第 7 版 UNIX™(1979 年,C89 标准定义前十年)中的 C 不再支持该表示法(但见下文)。

问题中显示的代码仅在所有结构的所有结构成员共享同一 namespace 时才有效。这意味着 structure.integpointer->integ 总是在结构的开头引用 int 因为只有一种可能的结构整个程序中的成员 integ

请注意,在“现代”C(1978 年以后)中,您不能引用结构类型;既没有结构标签也没有类型定义——类型是无用的。原始代码还引用了一个 undefined variable c

要让它工作,你需要像这样的东西:

#define PTR 0xAA000
struct integ {  int integ; };

int func(void)
{
   struct integ *ptr = (struct integ *)PTR;
   return ptr->integ;
}

第 7 版 UNIX 的 C

我建议第 7 版 UNIX 中的 C 支持单独的结构类型的单独 namespace 。但是,与 UNIX 程序员手册第 2 卷一起发布的 C 引用手册在§8.5 结构中提到:

The names of structure members and structure tags may be the same as ordinary variables, since a distinction can be made by context. However, names of tags and members must be distinct. The same member name can appear in different structures only if the two members are of the same type and if their origin with respect to their structure is the same; thus separate structures can share a common initial segment.

但是,同一手册还提到了符号(另请参见 What does =+ mean in C):

§7.14.2 lvalue =+ expression
§7.14.3 lvalue =- expression
§7.14.4 lvalue =* expression
§7.14.5 lvalue =/ expression
§7.14.6 lvalue =% expression
§7.14.7 lvalue =>> expression
§7.14.8 lvalue =<< expression
§7.14.9 lvalue =& expression
§7.14.10 lvalue =^ expression
§7.14.11 lvalue = | expression

The behavior of an expression of the form ‘‘E1 =op E2’’ may be inferred by taking it as equivalent to ‘‘E1 = E1 op E2’’; however, E1 is evaluated only once. Moreover, expressions like ‘‘i =+ p’’ in which a pointer is added to an integer, are forbidden.

AFAICR,我使用的第一个 C 编译器不支持它(1983 年——我很古老,但没那么古老);只允许使用现代的 += 符号。换句话说,我不认为该引用手册描述的 C 在产品发布时是完全最新的。 (我没有检查我的 K&R 的第 1 版 — 有没有人手头有检查?)您可以在 http://cm.bell-labs.com/7thEdMan/ 在线找到 UNIX 第 7 版手册。 .

关于c - ANSI C 之前的结构选择器使用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16109553/

相关文章:

c - 为堆中的结构元素分配内存?

c++ - 有没有地方可以下载 libgomp.spec?

c - 为什么我得到这个错误的输出?

c - Ubuntu 第一次编译内核模块

c - 如何将大十进制值转换为二进制

c++ - 声明指向对象的指针作为类成员对象的参数

c - 用于文件传输的多个套接字连接

c - 指针无法正确打印值

c - 为什么未初始化而不是越界?

macos - 在 OSX 上安装 Go 时出现 Ld 错误