一些神秘主义者与外界人士有关。指向C中的struct的指针

时间:2016-12-22 10:41:09

标签: c pointers struct extern

我有以下代码片段,其中包含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_tail num_head < / em>和 stack_head ),编译器( clang版本3.8.0 gcc 5.4.0 )编译此代码时没有错误,程序工作正常正如它应该。但是,就我而言,由于 structs.h 中缺少extern修饰符,此代码不应正常编译并正常工作。它为什么有效? :)

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

2 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:1)

默认情况下,不需要extern,因为非静态变量已经具有外部范围。

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

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

编译器仅针对重新定义的情况提供错误,例如,如果标头和来源中的num_tail 都已初始化