не может скомпилировать коды с помощью Microsoft Visual Studio C ++ 2008 Express Edition - PullRequest
0 голосов
/ 21 сентября 2011

У меня есть ac коды, которые можно скомпилировать в Linux с помощью gcc.Но когда я пытаюсь скомпилировать его с помощью Microsoft Visual Studio C ++ 2008 Express Edition, используя Ide, он показывает ошибку

vec.obj : error LNK2005: _INIT_SETA already defined in a.obj
fatal error LNK1169: one or more multiply defined symbols found

Я проверил файлы заголовков, и все они имеют защиту препроцессора для предотвращениязаголовок, который нужно включить несколько раз, например

#ifndef _vec_h_
#define _vec_h_

Затем я попытался скомпилировать его в командной строке Visual Studio,

cl main.c

Его можно скомпилировать.В чем проблема?

Ответы [ 3 ]

1 голос
/ 21 сентября 2011

Отправленная вами ошибка указывает на существование vec.c и a.c (при условии, что вы не пытаетесь связать в уже существующих объектных файлах), оба из которых определяют INIT_SETA. Это ошибка компоновщика, а не ошибка компиляции.

cl main.c только компилирует файл в объектный файл, никаких ссылок не происходит. Если вы попытаетесь связать все ваши объектные файлы вместе, используя (link.exe) из командной строки, вы все равно получите ту же ошибку. Найдите в двух файлах, перечисленных в сообщении об ошибке, несколько определений символа INIT_SETA.

Одним из возможных решений может быть объявление его extern в одном из двух файлов с его использованием, тогда эти два файла будут использовать один и тот же экземпляр.

Если оба файла должны иметь личные копии, вы должны удалить любые объявления extern INIT_SETA, появляющиеся в заголовочных файлах (и добавить static к определениям в каждом исходном файле).

1 голос
/ 21 сентября 2011

«найден один или несколько кратно определенных символов» - это ошибка компоновщика, а не ошибка компилятора. Это происходит, когда два или более объектных файла содержат определение для одного и того же символа. В этом случае как vec.obj, так и a.obj так или иначе содержат запись для символа _INIT_SETA, поэтому вам нужно выяснить, как источники для vec.obj и a.obj каждый вводят символ _INIT_SETA в свои соответствующие переводческие единицы (сборники).

Обратите внимание, что _INIT_SETA является сгенерированным компилятором символом для идентификатора C INIT_SETA. Возможно, определение INIT_SETA было встроено через расширение макроса? В этом случае объявление INIT_SETA, вероятно, должно быть объявлено static.

Наличие проблемы с несколькими символами не влияет на компиляцию исходных файлов; скорее этап связывания завершится неудачей, потому что компоновщик не знает, с какой _INIT_SETA записью связать.

0 голосов
/ 21 сентября 2011

I checked the header files, and all of them have the preprocessor guard to prevent the header to be included multiple times
Это только препятствует тому, чтобы препроцессор включал один файл заголовка несколько раз в один модуль компиляции (файл cpp). Таким образом, этот заголовок все еще включен в оба файла cpp, и этот заголовок определяет объект _INIT_SETA. Эту проблему можно избежать, если заголовки содержат только объявления, а не определения. (Без кода функции и глобальных переменных.)

Hpp файл:

#ifndef _vec_h_
#define _vec_h_
class vector {
    function();  //function prototype.  No definition
};  //class declaration.  No instantiation
extern vector myvector;   //variable declaration.  No instantiation
#endif //_vec_h_

Cpp файл:

#include "vec.h"

vector::function() {} //function definition only in this cpp file

vector myvector; //variable instantiation only in this cpp file

Единственными исключениями, как правило, являются шаблоны, которые целиком содержатся в заголовочном файле, и компоновщик сам это выясняет.

...