C语言 为什么这样的警告,即使类型在.h文件中指定

xj3cbfub  于 2023-10-16  发布在  其他
关注(0)|答案(3)|浏览(113)

有两个文件libtest. h和libtest. c
libtest.h

int a;

libtest.c

#include "libtest.h"

a = 10;

当我编译libtest. c
cc -c libtest. c
libtest.o被生成,但我得到这个警告。是什么原因呢?

libtest.c:3:1: warning: type specifier missing, defaults to 'int' [-Wimplicit-int]
a = 10;
^

如果我做同样的事情,但是在libtest. c中的某个函数中,

#include "libtest.h"

int foo()
{
    a = 10;
    return(0);
}

cc -c libtest. c
编译时没有任何警告。有什么区别吗?

lymnna71

lymnna711#

不能从函数外部赋值给变量。什么时候会调用这样的代码?
编译器将其解释为a变量的定义,来自旧的C语言,缺少类型默认为int

mgdq6dx1

mgdq6dx12#

你不能把语句(在这种情况下是赋值)放在函数之外。在声明中给变量一个值称为 * 初始化 *。此外,当你在头文件中声明一个变量时,它应该被声明为extern,它的定义应该放在相应的实现文件中。在所有导出的变量和函数前面加上模块名也是一个好主意,这样你就知道它们来自哪里。
范例:
M.h

#ifndef M_H
#define M_H

extern int M_a;

#endif

M.c

#include "M.h"

int M_a;

main.c

#include "M.h"

int main(void)
{
   M_a = 10;
   return 0;
}

ifndef-define宏用于避免头文件多次包含在同一个翻译单元中。
此外,一般来说,建议不要导出变量,而是导出可以保证变量完整性的get和set函数。例如,M_a 可能是一个变量,它应该总是非负的,在这种情况下,我们可以将setter定义为

void M_SetA(int val)
{
   assert(val >= 0);
   M_a = val;
}
eyh26e7m

eyh26e7m3#

你不能在一个函数之外 * 赋值 * 一个变量,只能 * 定义 * 和 * 初始化 *。从语法上讲,你的a = 10;a的一个 * 重新定义 *,这可能是随后的错误所清楚的。
要提供a的静态初始化,在头文件中应该有:

extern int a ;

然后在C源中;

#include "libtest.h"

int a = 10 ;

相关问题