简体   繁体   English

你如何定义头文件中的函数?

[英]How do you define functions in header files?

The setup设置

If I have a program like this如果我有这样的程序

A header file that declares my main library function, primary() and defines a short simple helper function, helper() .一个头文件,它声明了我的主库函数primary()并定义了一个简短的简单帮助函数helper()

/* primary_header.h */
#ifndef _PRIMARY_HEADER_H
#define _PRIMARY_HEADER_H

#include <stdio.h>

/* Forward declare the primary workhorse function */
void primary();

/* Also define a helper function */
void helper()
{
    printf("I'm a helper function and I helped!\n");
}
#endif /* _PRIMARY_HEADER_H */

The implementation file for my primary function that defines it.定义它的主要函数的实现文件。

/* primary_impl.c */
#include "primary_header.h"
#include <stdio.h>

/* Define the primary workhorse function */
void primary()
{
    /* do the main work */
    printf("I'm the primary function, I'm doin' work.\n");

    /* also get some help from the helper function */
    helper();
}

a main() file that tests the code by calling primary()一个main()文件,它通过调用primary()来测试代码

/* main.c */
#include "primary_header.h"

int main()
{
    /* just call the primary function */
    primary();
}

The Problem问题

Using使用

gcc main.c primary_impl.c

does not link because the primary_header.h file gets included twice and therefore there is an illegal double definition of the function helper() .不会链接,因为primary_header.h文件被包含两次,因此存在函数helper()的非法双重定义。 What is the correct way to structure the source code for this project such that double definitions do not happen?为该项目构建源代码以防止双重定义的正确方法是什么?

You almost never write a function inside a header file unless it is marked to always be inlined.您几乎从不在头文件中编写函数,除非它被标记为始终内联。 Instead, you write the function in a .c file and copy the function's declaration (not definition) to the header file so it can be used elsewhere.相反,您在.c文件中编写函数并将函数的声明(不是定义)复制到头文件,以便它可以在其他地方使用。

You should only write your function's prototype in the header file, the body of your function should be written in a .c file.你应该只在头文件中写你的函数原型,你的函数体应该写在一个 .c 文件中。

Do this :这样做:

primary_header.c主要_header.c

/* primary_header.h */
#ifndef PRIMARY_HEADER_H
#define PRIMARY_HEADER_H

#include <stdio.h>

/* Forward declare the primary workhorse function */
void primary(void);

/* Also define a helper function */
void helper(void);

#endif /* PRIMARY_HEADER_H */

primary_impl.c primary_impl.c

/* primary_impl.c */
#include "primary_header.h"
#include <stdio.h>

/* Define the primary workhorse function */
void primary()
{
    /* do the main work */
    printf("I'm the primary function, I'm doin' work.\n");

    /* also get some help from the helper function */
    helper();
}

void helper()
{
    printf("I'm a helper function and I helped!\n");
}

Edit: change _PRIMARY_HEADER_H to PRIMARY_HEADER_H .编辑:_PRIMARY_HEADER_H更改为PRIMARY_HEADER_H As @Jonathan Leffler and @Pablo said, underscore names are reserved identifiers正如@Jonathan Leffler 和@Pablo 所说,下划线名称是保留标识符

You can define a function in header files if it's weak linkage like:如果它是弱链接,您可以在头文件中定义一个函数,例如:

// test.h
__attribute__((weak)) int test() {
    static int s = 0;
    return s++;
}

// a.c
#include "test.h"
#include <stdio.h>
void a(){
    print("%d", test());
}

// b.c
#include "test.h"
#include <stdio.h>
void b(){
    print("%d", test());
}

// main.c
#include "test.h"
#include <stdio.h>
void a();
void b();

void main(){
    a();
    b();
    print("%d", test());
}

cc ac bc main.c won't raise multiple definitions error and the output should be 012 as expected, meaning ac , bc and main.c share the same test function. cc ac bc main.c不会引发多个定义错误,输出应该是预期的012 ,这意味着acbcmain.c共享相同的test功能。 You can achieve the same result in c++ by using inline .您可以通过使用inline在 c++ 中获得相同的结果。

Moreover, weak linkage can also be used on variable definition, allowing you to define and initialize a global variable in header files without source files (similar to inline static in c++).此外,弱链接还可以用于变量定义,允许您在没有源文件的头文件中定义和初始化全局变量(类似于 c++ 中的inline static )。

Note:注意:

Weak symbols are not mentioned by the C or C++ language standards. C 或 C++ 语言标准未提及弱符号。

So be careful when using it in c.所以在c中使用时要小心。 But in c++, inline and inline static are portable form c++11 and c++17.但是在 c++ 中, inlineinline static是可移植的形式 c++11 和 c++17。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM