一些神秘主义者 'extern' 指针指向 C 中的结构

Some mystic with 'extern' pointer to struct in C

我有以下代码片段,其中包含 3 个指向结构的全局指针:

structs.h:

#pragma once

typedef struct Bignum {
  int digit;
  struct Bignum *next;
  struct Bignum *prev;
} Bignum;

typedef struct Stack {
  struct Bignum *head;
  struct Bignum *tail;
  char sign;
  struct Stack *next;
} Stack;

Bignum *num_tail;
Bignum *num_head;
Stack *stack_head;

globals.c:

#include "structs.h"

Bignum *num_tail;
Bignum *num_head;
Stack *stack_head;

当我用其他 .c 文件编译这些文件时(我在其中包含 structs.h 并使用 num_tailnum_headstack_head),编译器(clang 版本 3.8.0gcc 5.4.0) 编译这段代码没有错误,程序可以正常工作。但是,就我而言,由于 structs.h 中缺少 extern 修饰符,此代码 不应 正常编译和工作。为什么它有效? :)

UPD: 是的,答案是暂定。实际上,在初始化指向 NULL 的指针后,编译器会给出一条错误消息。感谢大家的回复!

默认情况下不需要 extern 因为非静态变量已经有外部作用域。

事实上globals.c中的声明是多余的。

Bignum *num_tail;
Bignum *num_head;
Stack *stack_head;

编译器只会在重新定义的情况下给出错误,例如,如果头文件和源代码中的 num_tail 都已初始化

暂定定义。您没有为这些全局变量分配值,因此它们被视为暂定定义。假定右侧 ={0}; 但只是暂时的。如果没有真正的定义,临时定义将被合并。如果有的话,它会在不产生链接器冲突的情况下赢得暂定的。这通常是通过通用符号(在 nm 输出中标记为 C)实现的,这意味着即使在多个翻译单元中,您也可以对同一符号进行暂定定义。 (我认为最好不要依赖此功能并坚持使用 extern 声明和非暂定定义。)