【问题标题】:is it possible to have only header file in C without source file是否可以在没有源文件的情况下在 C 中只有头文件
【发布时间】:2018-04-16 13:37:58
【问题描述】:

我想通过只包含头文件而不使用编译库来编写一个可以快速访问的 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 应用程序中包含代码来仅使用头文件?

【问题讨论】:

  • 访问不会更快,因为你已经用C编译了头文件。在所有情况下,都必须进行函数调用。
  • 是的,但与库中的函数调用相反,代码本身的函数调用可以由编译器“优化”(内联,也许还有一些我不知道的东西)。
  • @Tom's,我同意,谢谢您的意见。

标签: c compilation header


【解决方案1】:

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

如果您有file1.cfile2.c,并且在它们每个中都包含您的coded.h,那么在编译的链接部分,将有2 个具有全局范围的测试函数(一个在file1.c另一个在file2.c)。

您可以使用“静态”一词来表示该功能将受到限制,因此它仅在包含coded.h.c 文件中可见,但话又说回来,这是个坏主意。

最后但同样重要的是:您打算如何制作一个没有.so/.a 文件的库?这不是图书馆;这是直接在您的项目中复制/粘贴代码。

当在您的“库”中发现错误时,除了更正您的代码、在每个项目中重新分配它并重新编译每个项目之外,您将别无解决方案,从而错过了动态库的关键点: “只是”更正库而不触及使用它的每个程序。

【讨论】:

    【解决方案2】:

    如果我理解您的要求正确,您希望创建一个“库”,它是严格意义上的源代码,在必要时获取#incuded,而不是单独编译和链接。

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

    此时您有几个选择。

    你可以声明函数static:

    static void test( void )
    {
      ...
    }
    

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

    您可以使用宏代替函数:

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

    除了宏不是函数,它的行为不像函数。虽然基于宏的“库”确实存在,但要正确实现它们并非易事,需要花很多心思。请记住,宏参数不会被评估,它们只是在原地扩展,如果您传递带有副作用的表达式,这可能会导致问题。经典的例子是:

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

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

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

    【讨论】:

      【解决方案3】:

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

      这是因为带有函数的.h文件被包含并编译在多个C源文件中。结果,链接器多次遇到具有全局范围的函数。

      您可以将函数定义为static,这意味着它的作用域仅适用于当前编译单元,因此:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-04-07
        • 2020-05-15
        • 2018-08-06
        • 1970-01-01
        • 2013-10-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多