Error public symbol defined in both module

Go Up to Clang-enhanced C++ Compilers

Go Up to Clang-enhanced C++ Compilers

Contents

  • 1 Controlling Warning Messages
  • 2 Common Errors Porting from BCC32
    • 2.1 ‘x’ does not refer to a value (in template)
    • 2.2 Missing ‘typename’ prior to dependent type name ‘x’
    • 2.3 Pasting formed ‘x’, an invalid preprocessing token
    • 2.4 Public symbol ‘x’ defined in both module A and B
    • 2.5 Use of undeclared identifier ‘x’ (in template)
  • 3 Common Warnings Porting from BCC32
    • 3.1 Conversion from string literal to ‘char *’ is deprecated
    • 3.2 Implicit conversion changes signedness
  • 4 See Also

Controlling Warning Messages

The option Enable all warnings (on Project > Options > C++ Compiler > Warnings) invokes the compiler with the -Weverything option, which is a superset of -Wall (for all «easy to avoid» constructions).

Warnings may be enabled or suppressed individually, which requires the name of the warning. To show these names, pass -fdiagnostics-show-option to the compiler. Doing so changes a warning like this:

File1.cpp:32:11: warning: unused variable 'foo'

to this:

File1.cpp:32:11: warning: unused variable 'foo' [-Wunused-variable]

You can then use -Wunused-variable to turn on that warning specifically, without enabling others. To disable that warning, replace the leading -W with -Wno-, and use it in combination with an option to enable the desired warning level. For example: -Wall -Wno-unused-variable will enable all easy to avoid warnings except for unused variables.

Common Errors Porting from BCC32

Code ported from BCC32 may exhibit some of these errors (listed alphabetically, ignoring placeholders like ‘x’).

‘x’ does not refer to a value (in template)

Type names that are dependent on the template parameter must be preceded by typename. Without it, for example:

template <class T>
void doSomething() {
  T::member *var;
}

a * intended for pointer declaration will actually be interpreted as multiplication; and if the intended variable already happens to be in scope, this error will occur, trying to multiply a type name (‘member’ in this example), which is not a value.

Missing ‘typename’ prior to dependent type name ‘x’

Type names that are dependent on the template parameter must be preceded by typename. When omitted, some edge cases may generate other errors, but in general the error and solution is clear.

Pasting formed ‘x’, an invalid preprocessing token

Token pasting with the preprocessor’s ## operator must form a single valid token. In many cases, the operator is not necessary in the first place, so simply removing it resolves the issue.

Public symbol ‘x’ defined in both module A and B

For example:

[ilink64 Error] Error: Public symbol 'triplet::sum' defined in both module C:USERSWIN764NODES.O and C:USERSWIN764UNIT1.O

Static data members should be declared in a header, and defined only once in a source file (not the header).

ILINK64 is documented here: Using ILINK32 and ILINK64 on the Command Line.

Use of undeclared identifier ‘x’ (in template)

Due to two-phase name lookup in templates, identifiers found in base classes are not resolved unless qualified with this->

Also, type names that are dependent on the template parameter must be preceded by typename. Without it, for example:

template <class T>
void doSomething() {
  T::member *var;
}

a * intended for pointer declaration will actually be interpreted as multiplication; and unless the intended variable already happens to be in scope, this error will occur, trying to multiply the template-value with the undeclared identifier (‘var’ in this example).

Common Warnings Porting from BCC32

Code ported from BCC32 may exhibit some of these warnings (listed alphabetically), which may be suppressed.

Conversion from string literal to ‘char *’ is deprecated

-Wdeprecated-writable-strings

Assigning a plain char pointer to a literal C-string is discouraged. Make the pointer const (and if appropriate, consider using std::string).

Implicit conversion changes signedness

-Wsign-conversion

BCC32 ignores an assignment from signed to unsigned.
Clang-enhanced C++ compilers do notice such assignments, and emit a warning or error message.

See Also

  • Stricter C++ Compilers (Clang-enhanced C++ Compilers)

Dinkin

733 / 524 / 129

Регистрация: 31.05.2013

Сообщений: 2,922

Записей в блоге: 3

1

18.08.2014, 11:39. Показов 8066. Ответов 17

Метки нет (Все метки)


Доброго! Стоит ли обращать внимания на варнинги такого типа, что отображает компилятор, к чему плохому они могут привести?

C
1
2
[ilink32 Warning] Warning: Public symbol '_speed' defined in both module
 C:RADTESTWIN32DEBUGUNIT1.OBJ and C:RADTESTWIN32DEBUGUNIT2.OBJ



0



Почетный модератор

Эксперт С++

5850 / 2861 / 392

Регистрация: 01.11.2011

Сообщений: 6,905

18.08.2014, 11:58

2

Цитата
Сообщение от Dinkin
Посмотреть сообщение

Стоит ли обращать внимания на варнинги такого типа

каждый тип надо рассматривать в отдельности. «Подобные варнинги» это не дело.

Цитата
Сообщение от Dinkin
Посмотреть сообщение

Public symbol ‘_speed’ defined in both module

Две одинаковые переменные.

Цитата
Сообщение от Dinkin
Посмотреть сообщение

к чему плохому они могут привести?

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



1



733 / 524 / 129

Регистрация: 31.05.2013

Сообщений: 2,922

Записей в блоге: 3

18.08.2014, 12:15

 [ТС]

3

Цитата
Сообщение от SatanaXIII
Посмотреть сообщение

Очевидно, что если две переменные с одинаковыми именами и разными значениями каким-то образом перепутаются

.
Да я понимаю что две переменные с одним названием.В данном случае у меня имеется две формы и в каждой форме я использую глобальную переменную «int i»…переменные ни где не пересекаются и используются каждая на своей форме…по логике нечего страшного, но думаю раз компилятор что то пишет, а вдруг чего то не знаю =)



0



Почетный модератор

Эксперт С++

5850 / 2861 / 392

Регистрация: 01.11.2011

Сообщений: 6,905

18.08.2014, 12:31

4

Цитата
Сообщение от Dinkin
Посмотреть сообщение

переменные ни где не пересекаются

После трансляции они все равно будут лежать рядышком. На то они и глобальные относительно всего приложения.

Цитата
Сообщение от Dinkin
Посмотреть сообщение

используются каждая на своей форме

Сделайте их членами формы.

Добавлено через 1 минуту

Цитата
Сообщение от SatanaXIII
Посмотреть сообщение

Сделайте их членами формы.

Или оберните в пустой namespace.



1



1448 / 1120 / 345

Регистрация: 11.04.2011

Сообщений: 2,615

18.08.2014, 12:33

5

Цитата
Сообщение от Dinkin
Посмотреть сообщение

имеется две формы и в каждой форме я использую глобальную переменную «int i»

Цитата
Сообщение от Dinkin
Посмотреть сообщение

переменные используются каждая на своей форме…

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



0



Dinkin

733 / 524 / 129

Регистрация: 31.05.2013

Сообщений: 2,922

Записей в блоге: 3

18.08.2014, 12:34

 [ТС]

6

Цитата
Сообщение от SatanaXIII
Посмотреть сообщение

Сделайте их членами формы

можно пояснить это.

Сейчас у меня так на каждой форме

C
1
2
3
4
5
6
7
8
9
10
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
 
#include "Unit3.h"
//---------------------------------------------------------------------------
#pragma resource "*.dfm"
TForm3 *Form3;
int i;
//---------------------------------------------------------------------------



0



kodv

1448 / 1120 / 345

Регистрация: 11.04.2011

Сообщений: 2,615

18.08.2014, 12:38

7

Dinkin, в Unit3.h

C++
1
2
3
4
5
6
// Предыдущий код
class TForm3 : public TForm
{
private:
    static int i;
// Далнейший код

в Unit3.cpp

C++
1
2
3
4
// Предыдущий код
TForm3 *Form3;
//int i;
// Далнейший код



1



733 / 524 / 129

Регистрация: 31.05.2013

Сообщений: 2,922

Записей в блоге: 3

18.08.2014, 12:47

 [ТС]

8

Ну то есть какие выводы я делаю:
Что замечание компилятора говорит о том что есть шанс того что значение переменных могут где нибудь пересечься…и луче этим не пренебрегать.



0



Супер-модератор

Эксперт Pascal/DelphiАвтор FAQ

32451 / 20945 / 8105

Регистрация: 22.10.2011

Сообщений: 36,213

Записей в блоге: 7

18.08.2014, 12:51

9

Dinkin, объяви переменные статическими (и не надо ее, как статическую, заносить внутрь класса формы, это лишнее. Либо одно, либо другое) — тогда подобного предупреждения не будет… Статическая переменная видима только в пределах того файла, в котором описана.



1



1448 / 1120 / 345

Регистрация: 11.04.2011

Сообщений: 2,615

18.08.2014, 12:56

10

Цитата
Сообщение от Dinkin
Посмотреть сообщение

и луче этим не пренебрегать.

Да не только этим. Лучше никакими предупреждениями компилятора не пренебрегать. В идеале, компилятор вообще никак не должен возражать против вашего кода (Errors: 0, Warnings: 0).

Цитата
Сообщение от Dinkin
Посмотреть сообщение

Ну то есть какие выводы я делаю

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



1



Dinkin

733 / 524 / 129

Регистрация: 31.05.2013

Сообщений: 2,922

Записей в блоге: 3

18.08.2014, 13:02

 [ТС]

11

Цитата
Сообщение от UI
Посмотреть сообщение

объяви переменные статическими

то есть это как предложил kodv выше?

Цитата
Сообщение от kodv
Посмотреть сообщение

без них можно легко обойтись

Суть что у меня в проекте грубо говоря сотни раз встречается

C
1
for(i=0;i<n;i++)

в целях экономии памяти я вывел i как глобальную, что бы ее каждый раз не объявлять в самом цикле, или это заблуждение?



0



volvo

Супер-модератор

Эксперт Pascal/DelphiАвтор FAQ

32451 / 20945 / 8105

Регистрация: 22.10.2011

Сообщений: 36,213

Записей в блоге: 7

18.08.2014, 13:10

12

Цитата
Сообщение от Dinkin
Посмотреть сообщение

то есть это как предложил kodv выше?

Нет, вот так:

C++
1
2
TForm1 *Form1;
static int i;



1



SatanaXIII

Почетный модератор

Эксперт С++

5850 / 2861 / 392

Регистрация: 01.11.2011

Сообщений: 6,905

18.08.2014, 13:15

13

Лучший ответ Сообщение было отмечено Dinkin как решение

Решение

Цитата
Сообщение от UI
Посмотреть сообщение

Статическая переменная видима только в пределах того файла, в котором описана.

Внутри единицы трансляции наверное будет вернее сказать.

Цитата
Сообщение от Dinkin
Посмотреть сообщение

в целях экономии памяти я вывел i как глобальную, что бы ее каждый раз не объявлять в самом цикле для экономии памяти, или это заблуждение?

Подобные случаи, со стандартными типами данных будут оптимизированны компилятором. Какие-то сложные запутанные методы с какими-нибудь своими типами данных лучше вот так вот стараться оптимизировать. Сейчас же вы просто мешаете компилятору заниматься своей работой.
Когда будете программировать контроллеры, с ограниченными ресурсами, и когда там станет вам действительно нехватать памяти, тогда вот и можно начинать заниматься подобной оптимизацией.

Возвращаясь непосредственно к вопросу темы:

Вариант номер один

C++
1
2
3
4
5
6
7
8
class TForm1 : public TForm
{
__published:    // IDE-managed Components
private:    // User declarations
        int i; // Переменная как член формы
public:     // User declarations
        __fastcall TForm1(TComponent* Owner);
};

Вариант номер два

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
#include <vcl.h>
#pragma hdrstop
 
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
static int i; // Статическая переменная
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{

Вариант номер три

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <vcl.h>
#pragma hdrstop
 
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
namespace
  {
  int i; // Переменная в безымянном пространстве имен
  }
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
        : TForm(Owner)
{



2



Uspenskiy_A_E

0 / 0 / 0

Регистрация: 22.07.2017

Сообщений: 2

22.07.2017, 20:38

14

Цитата
Сообщение от Dinkin
Посмотреть сообщение

Доброго! Стоит ли обращать внимания на варнинги такого типа, что отображает компилятор, к чему плохому они могут привести?

C
1
2
[ilink32 Warning] Warning: Public symbol '_speed' defined in both module
 C:RADTESTWIN32DEBUGUNIT1.OBJ and C:RADTESTWIN32DEBUGUNIT2.OBJ

Обращать внимание нужно на всё.
Этот конкретно жить не мешает, но на фоне этих можно не заметить других.

Причина сообщения в том что speed объявлен в двух модулях.
Как писали выше во всех модулях кроме одного speed должен быть с extern.
Помещать с extern в h файл, а без extern в один из cpp не удобно когда переменных много. Можно упустить чего нибудь.

Я делаю так:

файл kkm.h

C++
1
2
3
4
5
6
7
#ifndef EXTERN_KKMH
#define EXTERN_KKMH
#endif
 
EXTERN_KKMH AnsiString BaseSectionINI;
EXTERN_KKMH AnsiString IDFromParam;
EXTERN_KKMH int KassirPassword;

файл kkm.cpp

C++
1
#include "kkm.h"

другие файлы проекта куда включается kkm.h

C++
1
2
#define EXTERN_KKMH extern
#include "KKM.h"

Пояснения:
— #define действует до конца файла (с учетом #include)
— Это значит что при компиляции «других файлов проекта» EXTERN_KKMH будет определен как extern в файле kkm.h
— и соответственно
EXTERN_KKMH AnsiString BaseSectionINI;
превратится в
extern AnsiString BaseSectionINI;

А при компиляции kkm.cpp EXTERN_KKMH не определена и будет выполнен #define EXTERN_KKMH
И соответственно
EXTERN_KKMH AnsiString BaseSectionINI;
превратится в
AnsiString BaseSectionINI;

Ничего лучшего не нашел и не придумал.



0



1698 / 895 / 206

Регистрация: 25.11.2009

Сообщений: 1,845

22.07.2017, 22:00

15

Цитата
Сообщение от Uspenskiy_A_E
Посмотреть сообщение

Помещать с extern в h файл, а без extern в один из cpp не удобно когда переменных много

ИМХО, когда у Вас такое большое количество переменных, разделяемых между модулями, что приходится прибегать к таким манипуляциям, чтобы не загромождать код, это не лучшая реализация логики программы.
Запихните их в класс одной из форм. Либо в самостоятельный класс или структуру (можно вынести в отдельный заголовочный файл), экземпляр которого(ой) будет объявлен в одном юните, а в h-файле этого юнита будет extern.

Это, конечно, будет совсем не хитрая реализация, но зато явная и понятная.



0



0 / 0 / 0

Регистрация: 22.07.2017

Сообщений: 2

22.07.2017, 23:54

16

Цитата
Сообщение от Lelik-pahan
Посмотреть сообщение

ИМХО, когда у Вас такое большое количество переменных, разделяемых между модулями, что приходится прибегать к таким манипуляциям, чтобы не загромождать код,

Не важно 3 переменных или 33.
Важно что меняю имя, тип или добавляю/удаляю переменную в ОДНОМ месте.
Сокращается время и кол-во опечаток.

Цитата
Сообщение от Lelik-pahan
Посмотреть сообщение

это не лучшая реализация логики программы.

Не факт. Никто еще не доказал что не должно быть глобальных переменных которые используются в разных модулях.
А писать
sIP, fPrice
удобнее чем
Global->sIP, Global->fPrice

Цитата
Сообщение от Lelik-pahan
Посмотреть сообщение

Запихните их в класс одной из форм. Либо в самостоятельный класс или структуру

А если нет форм. И классы не нужны (их то же к слову надо объявлять)

Цитата
Сообщение от Lelik-pahan
Посмотреть сообщение

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

А вот от этого я предлагаю избавляться. см. начало.

А про манипуляции:
1 типовая лишняя строка в модулях
3 типовых лишних строки в заголовочном файле.
и в начале каждой строки с определением переменной типичное слово перед типом.

Мне не сложно.



0



1698 / 895 / 206

Регистрация: 25.11.2009

Сообщений: 1,845

23.07.2017, 01:19

17

Цитата
Сообщение от Uspenskiy_A_E
Посмотреть сообщение

Важно что меняю имя, тип или добавляю/удаляю переменную в ОДНОМ месте.

если обернуть все эти переменные в класс или структуру, также всё будет меняться только в одном месте

Цитата
Сообщение от Uspenskiy_A_E
Посмотреть сообщение

Никто еще не доказал что не должно быть глобальных переменных

я и не говорил, что их не должно быть. Но если так рассуждать, никто не доказал, что нельзя использовать goto, однако это не приветствуется.

Цитата
Сообщение от Uspenskiy_A_E
Посмотреть сообщение

А писать
sIP, fPrice
удобнее чем
Global->sIP, Global->fPrice

писать g.sIP, g.fPrice не намного сложнее. Глобальную переменную сразу видно, и локальные переменные юнита, работающие с этими же данными, не нужно называть иначе: sIP = g.sIP

Цитата
Сообщение от Uspenskiy_A_E
Посмотреть сообщение

А если нет форм.

на этот случай и написал про класс или структуру.

Цитата
Сообщение от Uspenskiy_A_E
Посмотреть сообщение

классы не нужны (их то же к слову надо объявлять)

кому они помешают? Объявление — одна лишняя строчка да скобки.

Цитата
Сообщение от Uspenskiy_A_E
Посмотреть сообщение

А вот от этого я предлагаю избавляться

Это я понял.

Спорить тут не имеет смысла, это дело вкуса, привычки и взаимопонимания с коллегами
Спасибо, что поделились своим «фокусом».



0



AndrSlav

68 / 56 / 14

Регистрация: 20.12.2013

Сообщений: 560

10.12.2017, 16:32

18

А как с этими переменными (если определены в 2 модулях трансляции одинаково без инструкции static, т.е. просто int i= 9; в каждом модуле глобально) действует программа? Т.е. вот у меня warning есть, но не ошибка. И что, эти переменные рассматриваются как статические для каждого модуля трансляции??

Добавлено через 11 минут
Глобально в файле с функцией main написал

C++
1
2
int yy= 99;
extern int uu;

В файле 2 проекта

C++
1
int yy= 90;

В файле 3

C++
1
2
extern int yy;
int uu= yy;

В результате uu=99. Т.е. во втором файле переменная yy рассматривается как локальная?

Добавлено через 4 минуты
Не совсем корректно поступил. Переписал 3 файл

C++
1
2
3
4
5
extern int yy;
int uu= yy;
 
int fuu()
{return uu;};

В файле с main добавил

C++
1
int gg= fuu();

И все равно gg=99, т.е. вопрос тот же.



0



Содержание

  1. Errors and Warnings of Clang-enhanced C++ Compilers
  2. Contents
  3. Controlling Warning Messages
  4. Common Errors Porting from BCC32
  5. ‘x’ does not refer to a value (in template)
  6. Missing ‘typename’ prior to dependent type name ‘x’
  7. Pasting formed ‘x’, an invalid preprocessing token
  8. Public symbol ‘x’ defined in both module A and B
  9. Use of undeclared identifier ‘x’ (in template)
  10. Common Warnings Porting from BCC32
  11. Conversion from string literal to ‘char *’ is deprecated
  12. Implicit conversion changes signedness
  13. Technical Details About ILINK32 and ILINK64
  14. Contents
  15. ILINK32
  16. Module Definition Files
  17. Linker-State Files
  18. Debug Information File
  19. ILINK64
  20. Handling ILINK64 Errors
  21. Errors and Warnings of Clang-enhanced C++ Compilers
  22. Contents
  23. Controlling Warning Messages
  24. Common Errors Porting from BCC32
  25. ‘x’ does not refer to a value (in template)
  26. Missing ‘typename’ prior to dependent type name ‘x’
  27. Pasting formed ‘x’, an invalid preprocessing token
  28. Public symbol ‘x’ defined in both module A and B
  29. Use of undeclared identifier ‘x’ (in template)
  30. Common Warnings Porting from BCC32
  31. Conversion from string literal to ‘char *’ is deprecated
  32. Implicit conversion changes signedness
  33. Ilink64 error public symbol defined in both module

Errors and Warnings of Clang-enhanced C++ Compilers

Contents

Controlling Warning Messages

The option Enable all warnings (on Project > Options > C++ Compiler > Warnings ) invokes the compiler with the -Weverything option, which is a superset of -Wall (for all «easy to avoid» constructions).

Warnings may be enabled or suppressed individually, which requires the name of the warning. To show these names, pass -fdiagnostics-show-option to the compiler. Doing so changes a warning like this:

You can then use -Wunused-variable to turn on that warning specifically, without enabling others. To disable that warning, replace the leading -W with -Wno- , and use it in combination with an option to enable the desired warning level. For example: -Wall -Wno-unused-variable will enable all easy to avoid warnings except for unused variables.

Common Errors Porting from BCC32

Code ported from BCC32 may exhibit some of these errors (listed alphabetically, ignoring placeholders like ‘x’).

‘x’ does not refer to a value (in template)

Type names that are dependent on the template parameter must be preceded by typename . Without it, for example:

a * intended for pointer declaration will actually be interpreted as multiplication; and if the intended variable already happens to be in scope, this error will occur, trying to multiply a type name (‘member’ in this example), which is not a value.

Missing ‘typename’ prior to dependent type name ‘x’

Type names that are dependent on the template parameter must be preceded by typename . When omitted, some edge cases may generate other errors, but in general the error and solution is clear.

Pasting formed ‘x’, an invalid preprocessing token

Token pasting with the preprocessor’s ## operator must form a single valid token. In many cases, the operator is not necessary in the first place, so simply removing it resolves the issue.

Public symbol ‘x’ defined in both module A and B

Static data members should be declared in a header, and defined only once in a source file (not the header).

Use of undeclared identifier ‘x’ (in template)

Due to two-phase name lookup in templates, identifiers found in base classes are not resolved unless qualified with this->

Also, type names that are dependent on the template parameter must be preceded by typename . Without it, for example:

a * intended for pointer declaration will actually be interpreted as multiplication; and unless the intended variable already happens to be in scope, this error will occur, trying to multiply the template-value with the undeclared identifier (‘var’ in this example).

Common Warnings Porting from BCC32

Code ported from BCC32 may exhibit some of these warnings (listed alphabetically), which may be suppressed.

Conversion from string literal to ‘char *’ is deprecated

Assigning a plain char pointer to a literal C-string is discouraged. Make the pointer const (and if appropriate, consider using std::string ).

Implicit conversion changes signedness

BCC32 ignores an assignment from signed to unsigned. Clang-enhanced C++ compilers do notice such assignments, and emit a warning or error message.

Источник

Technical Details About ILINK32 and ILINK64

For information on using ILINK32 and ILINK64 on the command line, please see the Using ILINK32 and ILINK64 on the Command Line page.

Contents

ILINK32

ILINK32 links object modules (.OBJ files), library modules (.LIB files), and resources to produce executable files (.EXE, .DLL, and .BPL files). ILINK32 creates and maintains a series of linker state files that contain this information. These state files allow subsequent links to be incremental, greatly reducing the total link time. See Linker-State Files and Debug Information File.

Module Definition Files

The module definition file is a text file that provides information to ILINK32 about the contents and system requirements of a Windows application. You can create a module definition file using IMPDEF.EXE, and you can create import libraries from module definition files using IMPLIB.EXE.

If no module definition file is specified, the following defaults are assumed:

To change the attributes of an application from these defaults, you need to create a module definition file.

If you delete the EXETYPE statement, the linker can determine what kind of executable you want to produce from the options you supply on the command line.

You can include an import library to substitute for the IMPORTS section of the module definition.

You can use the __declspec(dllexport) or _export keywords in the definitions of export functions in your C and C++ source code to remove the need for an EXPORTS section. Note, however, that if __declspec(dllexport) or _export is used to export a function, that function is exported by name rather than by ordinal. Please also note that __declspec(dllexport) is the preferred method of export.

Linker-State Files

The four linker-state files have the following file extensions:

  • .ILC (linker code file)
  • .ILD (linker data file)
  • .ILF (linker other file)
  • .ILS (linker symbols file)

These four files are required for incremental linking.

You can control the linker state files on the Project > Options > C++ Linker page, as follows:

  • To disable the creation of the linker state files, check the Disable incremental linking (-Gn) option.
  • To clear the current linker state files and create new ones in the next link operation, check the Clear state before linking (-C) option.

Debug Information File

If you include debug information in your final linked executable, ILINK32 will always store the debug information in a separate TDS debug file, named

.tds by default. The debugger should be able to read this debugger-information file. ILINK32 will always create this file. If you do not have the -v (or /v ) linker switch set, the debug symbol file is marked as invalid.

DCC32.exe (the Delphi compiler) has a command line switch -VT for generating debug symbol files. You can also specify that the Delphi compiler is to generate debug symbol files by enabling Place debug information in separate TDS file on the Linking page of Project Options.

ILINK64

ILINK64 is the linker for C++ 64-bit Windows applications. Command syntax and usage for ILINK64 are the same as those of ILINK32. The main differences between the two C++ linkers for Windows are:

  • ILINK32 links .obj and .lib files into a 32-bit Windows executable or .dll .
  • ILLINK64 links .o and .a files into a 64-bit Windows executable or .dll .

With these main differences, you use the two linkers in the same ways.

Handling ILINK64 Errors

BCC64 Errors and Warnings describes handling the following error from ILINK64, the C++ linker for 64-bit Windows:

Some projects have a large amount of debugging or other data that can cause errors in the linker using its default settings. For information on how to handle this type of error, see Handling Linker Out of Memory Errors or learn more about the Split DWARF feature that helps you reduce the linker memory usage.

Источник

Errors and Warnings of Clang-enhanced C++ Compilers

Contents

Controlling Warning Messages

The option Enable all warnings (on Project > Options > C++ Compiler > Warnings ) invokes the compiler with the -Weverything option, which is a superset of -Wall (for all «easy to avoid» constructions).

Warnings may be enabled or suppressed individually, which requires the name of the warning. To show these names, pass -fdiagnostics-show-option to the compiler. Doing so changes a warning like this:

You can then use -Wunused-variable to turn on that warning specifically, without enabling others. To disable that warning, replace the leading -W with -Wno- , and use it in combination with an option to enable the desired warning level. For example: -Wall -Wno-unused-variable will enable all easy to avoid warnings except for unused variables.

Common Errors Porting from BCC32

Code ported from BCC32 may exhibit some of these errors (listed alphabetically, ignoring placeholders like ‘x’).

‘x’ does not refer to a value (in template)

Type names that are dependent on the template parameter must be preceded by typename . Without it, for example:

a * intended for pointer declaration will actually be interpreted as multiplication; and if the intended variable already happens to be in scope, this error will occur, trying to multiply a type name (‘member’ in this example), which is not a value.

Missing ‘typename’ prior to dependent type name ‘x’

Type names that are dependent on the template parameter must be preceded by typename . When omitted, some edge cases may generate other errors, but in general the error and solution is clear.

Pasting formed ‘x’, an invalid preprocessing token

Token pasting with the preprocessor’s ## operator must form a single valid token. In many cases, the operator is not necessary in the first place, so simply removing it resolves the issue.

Public symbol ‘x’ defined in both module A and B

Static data members should be declared in a header, and defined only once in a source file (not the header).

Use of undeclared identifier ‘x’ (in template)

Due to two-phase name lookup in templates, identifiers found in base classes are not resolved unless qualified with this->

Also, type names that are dependent on the template parameter must be preceded by typename . Without it, for example:

a * intended for pointer declaration will actually be interpreted as multiplication; and unless the intended variable already happens to be in scope, this error will occur, trying to multiply the template-value with the undeclared identifier (‘var’ in this example).

Common Warnings Porting from BCC32

Code ported from BCC32 may exhibit some of these warnings (listed alphabetically), which may be suppressed.

Conversion from string literal to ‘char *’ is deprecated

Assigning a plain char pointer to a literal C-string is discouraged. Make the pointer const (and if appropriate, consider using std::string ).

Implicit conversion changes signedness

BCC32 ignores an assignment from signed to unsigned. Clang-enhanced C++ compilers do notice such assignments, and emit a warning or error message.

Источник

Ilink64 error public symbol defined in both module

Please contact us if you have any trouble resetting your password.

It may be an IDE specific problem but i encountered some weirdo voodoo situation with no ideas how to perform next.

I have two different projects (in two different folders) one for windows second for android. (i compile them on windows anyway)

For one i use Android Studio for second one i use RAD Studio, anyway they are two separated project sharing a library folder with source.

basically to share shared libraries i used:

mklink /D c:anroidproject1/share e:shared_lib

mklink /D e:projectsc++winproject2share e:shared_lib

Now shared libraries need to know either i want to compile WINDOWS or LINUX port so in each project root folder (which contains this share folder) i place three fies: PORTDEF.h, PATHDEF.h, PATH_DEF.cpp

where i put defines: (well actually ill show you the code maybe its important however header guards are used)

now in android project i have a main glcode.cpp file where i include

#include «PORT_DEF.h»
#include «PATH_DEF.cpp»

and files in share folder use them too in manner of that they are included with relative path

#include «../PORT_DEF.h»
#include «../PATH_DEF.cpp»

Hit build everything is fine and works…

However… on windows

There are 3 units. One is Project.cpp (which is the main compilation file) and Unit1.cpp, Unit2.cpp (along with their headers)

During writing this post i faced new issues so lets get over with it:

i hit compile and get multiple definition of ‘DATA_PATH’

No having no idea what would cause that, i started poking around and ended with something like that:

in file share/sharedlib1.h cannot find file “.PORTDEF.h” @ #include “../PORT_DEF.h”

After an hour of trys and fails, i came with an idea to to add PORT_DEF.h to a project. (so it wil be visible for compiler)

but this requires me to change from #include “../PORTDEF.h” to #include “PORT_DEF.h”

i tried this in Androdi Studio (basically added this to cmakelists.txt)

error: CMakeFiles/s/gl_code.cpp.o: multiple definition of ‘DATA_PATH’

so i actually reproduced the same error on two IDEs now how i am supposed to to get rid of this multiple definition thingy.

I was searching for circular references there are none

basically these are all files included

all cpp files have headerguards (ones that are included in #include) the same goes for all headers they too have headerguards

yet still even when including

PORT_DEF.h AND PATH_DEF.cpp at the beggining of project they shoul reside there

yet when hitting another file which uses these files it rants about mutiple declaration. . IM OUT OF IDEAS

This sounds really interesting and I guess there is no easy solution because of your overall setup. First, you don’t need header guards in your CPP files as every compilation unit runs exactly 1 single cpp file to produce object code unless you included cpp files anywhere which is a no-no and should be done only if there is no other option to achieve what you need.

Second, naming your header guards: You should take care that you don’t use “simple” naming for them. Are you sure there is not a file that already defines PATH_DEFH? My naming for those guards is always like the filename except I replace every dot by an underscore. For example

This helps to avoid most cases of unintended definition clashes for me.

Something you might want to try is to resetup your projects. Start with a new clean solution and set include paths properly to the folder at which you store your shared libraries code and use the library sub-folder to prefix inclusion. Our build tool for example generates such inclusion entries in for example Visual Studio in a way that it adds the module root folder to the project as include path and we barely have files in the module root but store everything in a sub-folder. This way our includes always are either common for everything that is not specific to any module and then we have for example the Math folder in the Math module that then prefixes the include of anything inside it. For example

Finally this helps at least to determine where each file came from

Источник

  • Forum
  • General C++ Programming
  • [Linker Warning] Public symbol defined i

[Linker Warning] Public symbol defined in both module

Hi!
I have following problem:

Namely,when I use keyword «extern» to get the value of standard variable (e.g.float,int,..) or array located in one file and use it in another file, everything works fine.
Problems appear when I recall to matrix variable (I use matrix.h library from http://www.techsoftpl.com/matrix/matlite.htm)then I got this message:

[Linker Warning] Public symbol ‘_slupek’ defined in both module C:PROGRAM FILESBORLANDCBUILDER6PROJECTS5.11.2009SLUPKI.OBJ and C:PROGRAM FILESBORLANDCBUILDER6PROJECTS5.11.2009KATY.OBJ

Below are listings maybe someone will find mistake.

slupki.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#ifndef SLUPKIH 
#define SLUPKIH 

#include "matrix.h" 


#ifndef _NO_NAMESPACE 
using namespace std; 
using namespace math; 
#define STD std 
#else 
#define STD 
#endif 

#ifndef _NO_TEMPLATE 
typedef matrix<double> Matrix; 
#else 
typedef matrix Matrix; 
#endif 
///////////////////////////////// 
Matrix slupki(); 

#endif //SLUPKIH 

slupki.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "matrix.h" 
#include "slupki.h" 
////////////////////////////// 
Matrix slupek(6,2); //matrix variable declaration
double x_1[6]; 
double x_2[6]; 

Matrix slupki() 
{ 
        for(int i=0;i<6;i++) 
        { 
         slupek(i,0)=3; 
         slupek(i,1)=3; 
         x_1[i]=slupek(i,0); 
         x_2[i]=slupek(i,1); 
        } 
        return(slupek); 
}

katy.h:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#ifndef KATYH 
#define KATYH 

#include "matrix.h" 

#ifndef _NO_NAMESPACE 
using namespace std; 
using namespace math; 
#define STD std 
#else 
#define STD 
#endif 

#ifndef _NO_TEMPLATE 
typedef matrix<double> Matrix; 
#else 
typedef matrix Matrix; 
#endif 
////////////////////////////// 
Matrix katy(); 

#endif //KATYH 

katy.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include "slupki.h" 
#include "matrix.h" 
///////////////////////////////////// 
double y_1[6]; 
double y_2[6]; 
//extern double x_1[6]; 
//extern double x_2[6]; 
Matrix kat(6,2); 
extern Matrix slupek(6,2); 

Matrix katy() 
{ 
       for(int i=0;i<6;i++) 
       { 
        kat(i,0)=slupek(i,0)+1; // recall to 1.column of matrix slupek(6,2) 
        kat(i,1)=slupek(i,1)+1; // recall to 2.column of matrix slupek(6,2) 
        y_1[i]=kat(i,0); 
        y_2[i]=kat(i,1); 
       } 
        return(kat); 
}

ftest.cpp:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
//--------------------------------------------------------------------------- 

#include <vcl.h> 
#pragma hdrstop 

#include "ftest.h" 
#include "katy.h" 
#include "slupki.h" 
//--------------------------------------------------------------------------- 
#pragma package(smart_init) 
#pragma resource "*.dfm" 
TForm1 *Form1; 
//--------------------------------------------------------------------------- 
__fastcall TForm1::TForm1(TComponent* Owner) 
        : TForm(Owner) 
{ 
} 
//--------------------------------------------------------------------------- 

void __fastcall TForm1::Button2Click(TObject *Sender) 
{ 
Close();        
} 
//--------------------------------------------------------------------------- 

void __fastcall TForm1::Button1Click(TObject *Sender) 
{ 
slupki(); 
katy(); 
extern double x_1[6]; 
extern double x_2[6]; 
extern double y_1[6]; 
extern double y_2[6]; 

for(int i=0;i<6;i++) 
{ 
StringGrid1->Cells[0][i]=AnsiString(x_1[i]); 
StringGrid1->Cells[1][i]=AnsiString(x_2[i]); 
StringGrid2->Cells[0][i]=AnsiString(y_1[i]); 
StringGrid2->Cells[1][i]=AnsiString(y_2[i]); 
} 
} 
//--------------------------------------------------------------------------- 

When I put extern double x_1[6] and extern double x_2[6] above katy() function in katy.cpp additionally I slash out extern Matrix slupek(6,2) and replace respectively slupek(i,0) and slupek(i,1) with x_1[i] and x_2[i] my program works fine.

Maybe the problem is in matrix.h library.

I work with Builder 6 Enterprise.
Any ifnormation concerning matrix.h can be found under http://www.techsoftpl.com/matrix/matlite.htm

I will be appreciate for any remarks.

katy.cpp

1
2
#include "slupki.h" // ?????? Is this right or should it be #include "katy.h"
#include "matrix.h"  

This can’t be right, but I don’t know why it compiles without error:

 
extern Matrix slupek(6,2); 

It should be

It should be #include «katy.h» but the outcome is the same as for #include «slupki.h»

But then ftest.cpp: includes both these files like this:

ftest.cpp:

1
2
#include "katy.h" 
#include "slupki.h"  

so you are no further forward.
You need to re-arrange your global variables

jsmith,

it doesn’t work with:

extern matrix slupek;

I got messages like this:

[C++ Error] katy.cpp(9): E2102 Cannot use template ‘matrix<T>’ without specifying specialization parameters

[C++ Error] katy.cpp(9): E2040 Declaration terminated incorrectly

[C++ Error] katy.cpp(15): E2268 Call to undefined function ‘slupek’

guestgulkan,
how to rearrange this?

Hang on, I got a bit confused there didn’t I? :-)

I got confused with slupki (which is a function) and slupek (which is a variable).
So ignore what I said in the previous posts.
//—————————————————————

So the problem is with the declaration of the slupek variable.
This Matrix slupek(6,2); and this extern Matrix slupek(6,2); are both the same
in that they are both definitions
One should be Matrix slupek(6,2); and the other should be extern Matrix slupek;.
So pretty much as JSmith said.

Last edited on

Now it works, ;-)

Thanks a lot guys!

Topic archived. No new replies allowed.

Выдаются два однотипных предупреждения:
[Linker Warning] Public symbol ‘_isNew’ defined in both module C:PROGRAM FILESBORLANDCBUILDER6PROJECTSRUSCHINATELUNIT1.OBJ and C:PROGRAM FILESBORLANDCBUILDER6PROJECTSRUSCHINATELUNIT2.OBJ
[Linker Warning] Public symbol ‘_isEdit’ defined in both module C:PROGRAM FILESBORLANDCBUILDER6PROJECTSRUSCHINATELUNIT1.OBJ and C:PROGRAM FILESBORLANDCBUILDER6PROJECTSRUSCHINATELUNIT2.OBJ

Соль в чем — в двух модулях — Unit1 и Unit2 имеются переменные с одинаковыми названиями:
bool isNew, isEdit;

Так вот, как с этим бороться и почему в Linker Warning указывается не isNew, а _isNew

7 ответов

246

17 сентября 2007 года

GIZMO

1.8K / / 30.07.2004

Выдаются два однотипных предупреждения:
[Linker Warning] Public symbol ‘_isNew’ defined in both module C:PROGRAM FILESBORLANDCBUILDER6PROJECTSRUSCHINATELUNIT1.OBJ and C:PROGRAM FILESBORLANDCBUILDER6PROJECTSRUSCHINATELUNIT2.OBJ
[Linker Warning] Public symbol ‘_isEdit’ defined in both module C:PROGRAM FILESBORLANDCBUILDER6PROJECTSRUSCHINATELUNIT1.OBJ and C:PROGRAM FILESBORLANDCBUILDER6PROJECTSRUSCHINATELUNIT2.OBJ

Соль в чем — в двух модулях — Unit1 и Unit2 имеются переменные с одинаковыми названиями:
bool isNew, isEdit;

Так вот, как с этим бороться и почему в Linker Warning указывается не isNew, а _isNew

а срр всегда (почти) имена коверкает,
вынести переменные в один модуль, а в другие подставлять через extern bool is Edit; в hрр

спасибо, понял… но лучше не выносить в один модуль, а просто изменить имена переменных… например isEdit2, isNew2… через extern немного неправильно будет — эти же переменные относятся к юнитам по-отдельности, т.е. связи между ними не должно быть…

PS: но такого клюка не вызывало раньше… объявлял похожие — и ни одного warning не было, может быть это из-за того что я написал в другой теме? ([Linker Error] Unresolved external)

12K

17 сентября 2007 года

__AleXX__

133 / / 02.04.2007

а лучше такие переменные объявлять статическими, тогда они точно не будут вылазить из видимости модуля.

что значит статическими? static int i ?

12K

18 сентября 2007 года

__AleXX__

133 / / 02.04.2007

да, это и значит.

просто был такой интересный момент — я в Unit2 переименовал переменную — навал ее из isEdit в isEdit2, и все равно такая же ошибка :) мол, в двух модулях используется название переменной isEdit2… Фокус, млин :)

а про static надо будет поподробнее почитать как нибудь… вдруг это очень важная вещь…

PS: просто я всегда без static обходился — и все ОК было…

Понравилась статья? Поделить с друзьями:
  • Error reading mbr victoria hdd
  • Error reading machine specific preferences they will be reset to defaults что делать
  • Error reading login count from pmvarrun
  • Error reading lock file etc network interfaces swp not enough data read
  • Error psx bios not found bios scph1001 bin что делать