代码之家  ›  专栏  ›  技术社区  ›  Schwern

头文件中的值导致“重复符号”链接器错误的结构

  •  2
  • Schwern  · 技术社区  · 15 年前

    这是一个更大项目的简化示例。你可以看到 here .

    我有一个包含系统时间函数限制的头文件。称之为time_config.h。

    #ifndef TIME_CONFIG_H
    #define TIME_CONFIG_H
    
    #define HAS_TIMEGM
    
    #define SYSTEM_LOCALTIME_MAX             2147483647
    #define SYSTEM_LOCALTIME_MIN            -2147483648
    #define SYSTEM_GMTIME_MAX                2147483647
    #define SYSTEM_GMTIME_MIN               -2147483648
    const struct tm SYSTEM_MKTIME_MAX = { 7, 14, 19, 18, 0, 138, 0, 0, 0, 0, 0 };
    const struct tm SYSTEM_MKTIME_MIN = { 52, 45, 12, 13, 11, 1, 0, 0, 0, 0, 0 };
    
    #endif
    

    然后有一个头文件定义我的时间函数。叫它我的时间。它包括time_config.h。

    #ifndef MYTIME_H
    #define MYTIME_H
    
    #include "time_config.h"
    
    #ifndef HAS_TIMEGM
    time_t timegm(const struct tm*);
    #endif
    
    #endif
    

    我把它编译成一个对象文件。。。

    gcc <a lot of warning flags> -I. -c -o mytime.o mytime.c
    

    并将其链接到一个测试二进制文件中,t/year\u limit.t.c还包括mytime.h。

    gcc <a lot of warning flags> -I. mytime.o t/year_limit.t.c -o t/year_limit.t
    

    ld: duplicate symbol _SYSTEM_MKTIME_MAX in /var/folders/eJ/eJzTVP7oG7GVsKYHJtMprE+++TI/-Tmp-//ccMe5DXb.o and mytime.o
    collect2: ld returned 1 exit status
    

    因为time_config.h是在构建过程中由系统探测器生成的,所以将所有值保存在一个头文件中,甚至多个头文件中会非常方便。在构建过程中修改.c文件更加困难。

    它在没有结构的情况下运行良好。如何在头文件中声明最小/最大日期结构而不引起此冲突?还是我编译和链接不正确?

    这是ANSI C89。

    4 回复  |  直到 15 年前
        1
  •  4
  •   dirkgently    15 年前
    const struct tm SYSTEM_MKTIME_MAX = { 7, 14, 19, 18, 0, 138, 0, 0, 0, 0, 0 };
    

    上面声明并定义了对象 SYSTEM_MKTIME_MAX ; 标题的多个包含导致多个定义。

    放入 extern

        2
  •  5
  •   Paul R    15 年前

    在标题(.h)中,您需要:

    extern const struct tm SYSTEM_MKTIME_MAX;
    extern const struct tm SYSTEM_MKTIME_MIN;
    

    在实现(.c)中,您需要:

    const struct tm SYSTEM_MKTIME_MAX = { 7, 14, 19, 18, 0, 138, 0, 0, 0, 0, 0 };
    const struct tm SYSTEM_MKTIME_MIN = { 52, 45, 12, 13, 11, 1, 0, 0, 0, 0, 0 };
    
        3
  •  2
  •   Alexander Poluektov    15 年前

    在C中,常量具有外部链接,因此应在.C文件中定义。

    在C++中,它们具有内部链接,因此可以在头文件中定义。

        4
  •  0
  •   Dewfy    15 年前

    标题必须仅包含声明。因此,将标题更改为:

    extern const struct tm SYSTEM_MKTIME_MAX;
    

    const struct tm SYSTEM_MKTIME_MAX = {...