как избежать этой ошибки связывания? - PullRequest
0 голосов
/ 26 мая 2010

если я определил глобальную переменную (с инициализацией) в заголовочном файле и включил этот файл в два файла и попытался скомпилировать и связать, компилятор выдаст ошибку связывания

headers.h:

#ifndef __HEADERS
#define __HEADERS
int x = 10;
#endif

1.c:

#include "headers.h"
main ()
{
}

2.c:

#include "headers.h"
fun () {}

Ответы [ 4 ]

5 голосов
/ 26 мая 2010

Компоновщик жалуется, потому что будет несколько определений x, как только он соберет все объектные файлы вместе, чтобы создать исполняемый файл.У вас есть два разных исходных файла, включая один и тот же заголовочный файл, и этот заголовочный файл определяет переменную x, имеющую значение 10, поэтому в итоге вы получите два определения x (одно в 1.c, а другое в 2.c).

Чтобы избежать ошибок компоновщика нескольких определений, поместите это в заголовочный файл (например, globals.h):

#ifndef GLOBALS_H
#define GLOBALS_H

/* 
 * The "extern" keyword means that this variable is accessible everywhere
 * as long as this declaration is present before it is used. It also means
 * that the variable x may be defined in another translation unit. 
 */
extern int x;

#endif

Затем вставьте в one исходный файл:

#include "globals.h"

int x = 10; 
1 голос
/ 26 мая 2010

# include работает точно так же, как если бы вы скопировали и вставили текст из заголовочного файла.

Рассмотрите это таким образом, и вы увидите, что вы поместили строку int x=10 в в ваших исходных файлов.

Ниже приведена фиксированная версия:

>>headers.h
#ifndef __HEADERS
#define__HEADERS
extern int x;  // extern tells the compiler it will be linked from another file
#endif
-----------------
>>1.c
#include "headers.h"
int x = 10;  // must have it in ONE file for linking purposes
main ()
{
}
---------------------
>>2.c
#include "headers"
fun () {}
1 голос
/ 26 мая 2010

Это классический случай, когда требуется либо объявленная переменная, либо объявленная и определенная.

Если вы определите его в обоих исходных файлах, вы получите ошибку компоновщика двойного определения. Один из способов справиться с этим - установить __HEADERS только для одного из исходных файлов, чтобы в нем определялась переменная.

Все остальные исходные файлы получают только объявление.

>>headers.h
    #ifndef __HEADERS
        int x = 10;
    #else
        extern int x;
    #endif

>>1.c
    #define __HEADERS
    #include "headers.h"
    int main (void) {
        return 0;
    }

>>2.c
    #include "headers"
    void fun (void) {
    }

Конечно, лучше вообще не указывать определения в заголовочных файлах, если вы случайно определили __HEADERS в двух исходных файлах. Попробуйте:

>>headers.h
    extern int x;

>>1.c
    #include "headers.h"
    int x = 10;
    int main (void) {
        return 0;
    }

>>2.c
    #include "headers"
    void fun (void) {
    }
1 голос
/ 26 мая 2010
  1. Определите __HEADERS в ifndef.
  2. Поместите в заголовки объявления, а не определения:
// header

extern int x;

 // implementation

int x = 10;

3. 2.c имеет неправильное включение.

Итак:

// headers.h

#ifndef __HEADERS
#define __HEADERS
    extern int x;
#endif

// 1.c

#include "headers.h"

int x = 10;

main ()
{
}

// 2.c

#include "headers.h"
fun () {}

Вы можете определить x где угодно. Просто сделай это в одном месте.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...