多次包含标题库时重复符号

问题描述 投票:1回答:1

我为我正在制作的小游戏制作了一个简单的帮助库。在这样的库中,我有一些必须尽可能快地执行的核心功能,因为它们每个游戏帧被调用了数千次。

如果我声明它们是“内联”并将它们的声明(library.h)从它们的实现(library.c)中分离并将它们包含在游戏文件(game.c)中,我猜它们没有内联/优化,因为它们直接在game.c中声明它们并编译游戏与gcc -O3相比,我的性能提升了60倍。

为了解决这个问题,我决定让我的库成为一个只有头的库。我在library.h中拥有所有框架常量,变量和函数。将它包括在game.c仍然给我最大的性能。

现在,问题在于每当我将library.h包含在多个文件中时(比如game1.cgame2.c),我在编译游戏时会得到一长串的duplicate symbol错误。该库有#pragma once但仍然出现问题。

如何实际编写仅限标头的库或确保实际优化外部库中的内联函数?

谢谢

c
1个回答
2
投票

正如已经评论过的,你需要在头文件static中声明函数和全局变量。

static关键字表示对象(函数或变量)具有内部链接;它只在当前编译单元中可见,并且不会包含在任何符号表中。

使用包含警卫也是一个好主意,因此如果您有另一个包含标题的头文件,并且C源文件包含头文件和其他头文件,则头文件只包含一次。 (FOOLIB_H的行包括以下示例中的包含警戒。)

考虑以下简单的固定大小的堆栈示例foolib.h:

#ifndef   FOOLIB_H
#define   FOOLIB_H

#include <stdlib.h>

#define   STACK_MAX  256

static size_t  stack_size = 0;
static double  stack_item[STACK_MAX];

static inline int  stack_push(const double  item)
{
    if (stack_size < STACK_MAX) {
        stack_item[stack_size++] = item;
        return 0;
    } else
        return -1;
}

static inline double  stack_pop(const double  empty)
{
    if (stack_size > 0)
        return stack_item[--stack_size];
    else
        return empty;
}

#endif /* FOOLIB_H */

每个编译单元(你单独编译的每个源文件)包含上面的(#include "foolib.h"),它们可以通过stack_push()stack_pop()获得他们自己的本地私有堆栈。

标记函数static inline而不仅仅是static的原因是前者告诉编译器可以完全省略该函数,如果没有使用它。特别是,如果使用gcc -Wall编译代码,gcc会在未使用static函数时发出警告,但如果未使用static inline函数则不会发出警告。除此之外,没有太大的实际差异。

© www.soinside.com 2019 - 2024. All rights reserved.