是否有可能只有没有源文件的C头文件

时间:2018-04-16 13:37:58

标签: c compilation header

我想编写一个快速访问的C库,只包含头文件而不使用编译库。为此,我已将我的代码直接包含在我的头文件中。

头文件包含:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#ifndef INC_TEST_H_
#define INC_TEST_H_

void test(){
    printf("hello\n");
}

#endif

我的程序无法编译,因为我有多个函数test()的引用。如果我有一个正确的源文件与我的标题,它可以正常工作。

是否可以通过在C app中包含代码来仅使用头文件?

3 个答案:

答案 0 :(得分:6)

在标题中包含代码通常是一个非常糟糕的主意。

如果您有“file1.c”和“file2.c”,并且在每个中都包含您的“编码.h”,那么在编译的链接部分,将有2个具有全局范围的测试功能(一个在file1.c中,另一个在file2.c中)。

你可以使用“静态”这个词,以便说明该函数仅限于包含“编码.h”的.c中,但是再次,这是一个坏主意。

至少但不是最后一个:你打算如何创建一个没有.so / .a文件的库?这不是库,这是您项目中直接复制/过去的代码。

当你的“库”中出现错误时,除了纠正你的代码,在每个项目中重新发布它并重新编译每个项目,你都将无法解决问题,忽略了动态库的重点:能够“只是“更正库而不触及使用它的每个程序。

答案 1 :(得分:3)

如果我理解你正确的要求,你想创建一个&#34;库&#34;这是严格的源代码,必要时获得#incude d,而不是单独编译和链接。

正如您所发现的,当您处理函数时,这并不容易 - 编译器会抱怨多个定义(对象定义会遇到同样的问题)。

此时你有几个选择。

您可以声明函数static

static void test( void )
{
  ...
}

static关键字限制了该功能对当前翻译单元的可见性,因此您不会在链接时遇到多个定义错误。这意味着每个翻译单元都在创建自己独立的&#34;实例&#34;该函数,导致一些代码膨胀和稍长的构建时间。如果你能忍受,那么这是最简单的解决方案。

您可以使用宏代替函数:

#define TEST() (printf( "hello\n" ))

除了宏不是函数并且不像函数那样。而基于宏观的&#34;图书馆&#34;确实存在,它们并不是无法正确实现的,需要相当多的思考。请记住,宏参数不会被评估,它们只是在适当的位置进行扩展,如果传递带副作用的表达式,可能会导致问题。典型的例子是:

#define SQUARE(x) ((x)*(x))
...
y = SQUARE(z++);

SQUARE(z++)扩展为((z++)*(z++)),这会导致未定义的行为。

单独编译是一件好事,你不应该试图避免它。在一个源文件中执行所有是不可扩展的,并且会导致维护问题。

答案 2 :(得分:2)

  

我的程序没有编译,因为我有多个对test()函数的引用

这是因为包含该函数的.h文件并在多个C源文件中编译。因此,链接器会多次遇到具有全局作用域的函数。

您可以将函数定义为static void test() { printf("hello\n"); } ,这意味着它只有curent编译单元的范围,所以:

{{1}}