C - 构建大型项目期间的多个功能定义

Posted

技术标签:

【中文标题】C - 构建大型项目期间的多个功能定义【英文标题】:C - multiple definition of function during building large project 【发布时间】:2015-06-13 14:36:29 【问题描述】:

我正在尝试构建大型项目,其中我有以下头文件

错误.h

#ifndef __ERROR_H__
#define __ERROR_H__

#include <stdio.h>
#include <stdlib.h>

void error_validate_pointer(void *ptr)

    if (ptr == NULL)
    
        puts("Error with allocating memory");
        exit(1);
    


#endif /* __ERROR_H__ */

我经常在我拥有的每个 .c 文件中使用这个函数(我在每个文件中都包含“error.h”),但我认为这个 #ifndef 可以保护我免受多重定义错误的影响。然而,在构建过程中,我收到以下错误:

../dictionary/libdictionary.a(state_list.c.o): In function `error_validate_pointer':
/home/pgolinski/Dokumenty/Programowanie/spellcheck-pg359186/src/dictionary/error.h:8: multiple definition of `error_validate_pointer'
../dictionary/libdictionary.a(hint.c.o):/home/pgolinski/Dokumenty/Programowanie/spellcheck-pg359186/src/dictionary/error.h:8: first defined here
../dictionary/libdictionary.a(state_set.c.o): In function `error_validate_pointer':
/home/pgolinski/Dokumenty/Programowanie/spellcheck-pg359186/src/dictionary/error.h:8: multiple definition of `error_validate_pointer'
../dictionary/libdictionary.a(hint.c.o):/home/pgolinski/Dokumenty/Programowanie/spellcheck-pg359186/src/dictionary/error.h:8: first defined here

我不断收到这些错误的原因可能是什么?如何避免?

【问题讨论】:

在每个文件中声明函数static。这是一个链接器错误。您试图解决它的预处理器机制不起作用。编译器完全独立于其他所有源文件来处理每个源文件。换句话说,它每次开始处理源文件时都会“忘记”所有先前的定义。 ifndef/define 用于防止在在给定源文件上工作时“重复定义”,但不能超出它。在编译结束时,多个实例(全局函数或变量)被视为链接错误。 通常 .h 文件不包含实际代码。通常它们只包含声明和/或预处理器#defines 和宏。 【参考方案1】:

发生这种情况是因为您多次#include 一个定义,因此您实际上最终有多个定义 - 每个包含它的文件一个。

将您的代码更改为

#ifndef __ERROR_H__
#define __ERROR_H__

#include <stdio.h>
#include <stdlib.h>

void error_validate_pointer(void *ptr);

#endif /* __ERROR_H__ */

...对于头部,所以它只包含函数的声明。

然后使用定义创建一个新文件(例如error.c

#include "error.h"

void error_validate_pointer(void *ptr)

    if (ptr == NULL)
    
        puts("Error with allocating memory");
        exit(1);
    

【讨论】:

【参考方案2】:

或者将函数分离到它自己的C文件中,如果你将函数声明为静态,你可以在头文件中定义它。如果你放置 inline 也是 gcc 不会编译未使用的静态函数。通过将其声明为静态函数,它的名称将不会在目标文件之外可见,因此您不会发生冲突。这将导致函数被多次定义,因此它会使您的代码更大,具体取决于您使用它的频率。

你的代码最终会是:

#ifndef __ERROR_H__
#define __ERROR_H__

#include <stdio.h>
#include <stdlib.h>

static inline void error_validate_pointer(void *ptr)

    if (ptr == NULL)
    
        puts("Error with allocating memory");
        exit(1);
    


#endif /* __ERROR_H__ */

【讨论】:

以上是关于C - 构建大型项目期间的多个功能定义的主要内容,如果未能解决你的问题,请参考以下文章

Flash - 管理大型项目

在 SQL Server 数据库项目构建期间使用错误的编译器

Spring Boot Gradle 多项目构建在测试期间看不到内部依赖项

在构建管道期间覆盖发布配置文件的发布文件夹 (url)

访问大型 C/C++ 项目中的现有字段

在编译时为大型 C/C++ 项目使用 GNU m4