头文件中的const定义,使用宏常量导致链接器多重定义错误

const definition in a header file, using macro constants causes linker multiple definition errors

你好!虽然我之前通过谷歌搜索在这里找到了我的编程问题的解决方案,但这是我第一次提出问题,因为我无法通过谷歌搜索找到答案。

我是一名专业的电子工程师,但不是软件工程师。我的(有限的)软件技能是自学的,由于缺乏理解,我在 C 编程方面尤为挣扎。所以请把我当作一个绝对的新手,并尽可能简单地解释我做错了什么,以及如何解决它的建议。

我是 compiling/linking 一个使用 Phar Lap compiler/linker 套件的基于 DOS 的旧 PC 的程序。我的几个 C 模块都有#include“codes.c”,我在下面包含了该头文件的摘录。只是按顺序排列的相关行,省略了中间不相关的行。 (顺便说一句,值 'LAST_IRTYPE' 在文件中较早定义,值为 9。)

#ifndef CODES_H
    #define CODES_H

#include "AStypes.h"                        // Typedefs for common types

#define IRtime(x)   ((x/IRtimeClkPer_us) + 0.5)


const uShort_16 cusarIRtimes[LAST_IRTYPE + 1][6] =  /* carrier pulse-times expressed in timer counts.
                                                    NB: IRtimeClkPer_us MUST be #defined (not in
                                                    this file!) for every project using this file!
                                                    (comment times are in ms:
                                                    start-pulse, start-gap, '0', '1', bit-gap, inter-command gap) */
{
    {IRtime(250), IRtime(2474), IRtime(2474), IRtime(3582), IRtime(250), IRtime(7000)},     // 0 = dbx 4BX (0.25, 2.474, 2.474, 3.582, 0.25, 7)
    {IRtime(2348), IRtime(580), IRtime(580), IRtime(1168), IRtime(580), IRtime(25000)},     // 1 = Sony 12-bit (2.348, 0.58, 0.58, 1.168, 0.58, 25)
    {IRtime(2348), IRtime(580), IRtime(580), IRtime(1168), IRtime(580), IRtime(25000)},     // 2 = Sony 16-bit (2.348, 0.58, 0.58, 1.168, 0.58, 25)
    {IRtime(8424), IRtime(4192), IRtime(520), IRtime(1576), IRtime(520), IRtime(20000)},    // 3 = JVC (8.424, 4.192, 0.52, 1.576, 0.52, 20)
    {IRtime(9040), IRtime(4560), IRtime(552), IRtime(1672), IRtime(552), IRtime(40000)},    // 4 = Squeezebox 3 (9.04, 4.56, 0.552, 1.672, 0.552, 40)
    {IRtime(9000), IRtime(4560), IRtime(552), IRtime(1672), IRtime(552), IRtime(40000)},    // 5 = Medion, 5BX, Oppo, Toppy (9, 4.56, 0.552, 1.672, 0.552, 40)
    {IRtime(4500), IRtime(4500), IRtime(560), IRtime(1680), IRtime(470), IRtime(45000)},    // 6 = LG BD, Samsung (4.55, 4.55, 0.560, 1.68, 0.515, 45)
    {IRtime(8512), IRtime(4272), IRtime(536), IRtime(1592), IRtime(536), IRtime(40000)},    // 7 = Pioneer GR-777 (8.512, 4.272, 0.536, 1.592, 0.536, 40)
    {IRtime(8512), IRtime(4272), IRtime(536), IRtime(1592), IRtime(536), IRtime(26000)}     // 8 = Pioneer DVD (8.512, 4.272, 0.536, 1.592, 0.536, 26)
};

    // Bits per code for 4BX, Sony1, Sony2, JVC, SB3, DTV, LGBD, STV, Pioneer1, Pioneer2:
const uChar_8 cucarBitsPerCode[LAST_IRTYPE + 1] = {6, 12, 15, 16, 32, 32, 32, 32, 32};

    /* Whether bits are sent as 'high' (IR on +) or 'low' (IR off -) for
        4BX, Sony1, Sony2, JVC, SB3, DTV, LGBD, STV, Pioneer1, Pioneer2: */
const Bool_8 bIRbitsHigh[LAST_IRTYPE + 1] = {bFALSE, bTRUE, bTRUE, bFALSE, bFALSE, bFALSE, bFALSE, bFALSE, bFALSE};

#endif

我对使用#ifndef CODES_H / #define CODES_H 的理解是,编译器只会在第一次遇到文件时 parse/compile 文件内容,因此其中定义的任何变量都会只被定义一次,但这似乎并没有发生。

当我 compile/link 我的程序时,我得到了一系列链接器错误,如下所示,除了一个 #include codes.h


386|LINK: 8.02 -- Copyright (C) 1986-96 Phar Lap Software, Inc.
Error LINK.3070: Duplicate definition of the symbol "cusarIRtimes" in module "funcs.c".
Error LINK.3070: Duplicate definition of the symbol "cucarBitsPerCode" in module "funcs.c".
Error LINK.3070: Duplicate definition of the symbol "bIRbitsHigh" in module "funcs.c".

使用 Notepad++ 加载 all .C 和 .H 文件,并在所有打开的文件中搜索 cusarIRtimes,它是只有在那一个地方,如上。

任何人都可以解释为什么链接器会找到重复的定义,以及我该如何纠正这个问题?谢谢。

丹尼尔

My understanding of using #ifndef CODES_H / #define CODES_H is that the compiler will only parse/compile the file's contents the first time it's encountered, so any variables defined within will only be defined once, but this doesn't seem to be happening.

它正在发生,但它是每个翻译单元(C 模块)一次,它们是相互独立编译的。您可以通过将 cusarIRtimescucarBitsPerCodebIRbitsHigh 的定义移动到您的一个 C 模块中并在包含文件中用声明替换它们来更正此问题:

extern const uShort_16 cusarIRtimes[LAST_IRTYPE + 1][6];
extern const uChar_8 cucarBitsPerCode[LAST_IRTYPE + 1];
extern const Bool_8 bIRbitsHigh[LAST_IRTYPE + 1];