Головоломка с const
От: Shmj Ниоткуда  
Дата: 13.01.23 22:23
Оценка: -1 :))) :))) :))) :))) :))
Такой вопрос-загадка.

Понадобилось собрать QT5 -проект на MacOS. Под Windows собрался успешно. Там были строки вида:

#pragma once
....
constexpr char* Value1 = "sdfsdfasf";


— в h-файле с в глобальном пространстве имен. constexpr компилятор отверг (чего-то там с версией C++ связано). Ну ок, допустим компилятор не понимает constexpr.

Второе. Заменил на const, типа так:

#pragma once
....
const char* Value1 = "sdfsdfasf";


Потратил еще кучу времени на сборку — уже на этапе линковки возникла ошибка — пишет что переменная Value1 объявлена дважды или что-то такое. Один файл мой, другой какой-то комбинированный. При этом на Windows все успешно собралось.

Ну ок, заменил #pragma once на:

#ifndef MY_H
#define MY_H
...
const char* Value1 = "sdfsdfasf";
#endif /* !MY_H */


Пол часа жду — та же фигя

Потом добавил:

static const char* Value1 = "sdfsdfasf";


— и о чудо — оно собралось.

Что это могло быть? Какие гипотезы?
Отредактировано 13.01.2023 22:24 Shmj . Предыдущая версия .
Re: Головоломка с const
От: kov_serg Россия  
Дата: 13.01.23 22:27
Оценка: +6
Здравствуйте, Shmj, Вы писали:

S>Пол часа жду — та же фигя


S>Что это могло быть? Какие гипотезы?


Гипотеза очень простая: Вы не очень представляете как оно работает на самом деле.
Re: Головоломка с const
От: Pzz Россия https://github.com/alexpevzner
Дата: 13.01.23 22:29
Оценка: 3 (1) +2
Здравствуйте, Shmj, Вы писали:

S>Что это могло быть? Какие гипотезы?


Ну у тебя твой ашник в два (или более) разных сишника включается. В каждом из них создается глобальный символ Value1. А когда линкер пытается свести все это вместе, то он видит, что один и тот же символ объявлен дважды в разных местах, и ругается.

Слово static делает символ локальным, проблема разрешается, но строка заведется отдельная в каждом сишнике (а в исполняемом файле будет присутствовать много копий одной строки). Почему вендовый линкер не ругается? Ну видимо, сознательно ведет себя неправильно, чтобы таких бедолаг, как ты, не расстраивать.
Re: Головоломка с const
От: rg45 СССР  
Дата: 13.01.23 22:37
Оценка: +3
Здравствуйте, Shmj, Вы писали:

S>Второе. Заменил на const, типа так:


S>
S>#pragma once
S>....
S>const char* Value1 = "sdfsdfasf";
S>


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

const char* Value1 = "sdfsdfasf";
char* const Value2 = "sdfsdfasf";
const char* const Value3 = "sdfsdfasf";


Как по-твоему, чем отличаются эти три объявления?

S>Потом добавил:

S>
S>static const char* Value1 = "sdfsdfasf";
S>

S>- и о чудо — оно собралось.
S>Что это могло быть? Какие гипотезы?

Гипотезы

Я тебе давно сказал
Автор: rg45
Дата: 05.01.23
— читай про связывание. Вопросы тебе на самостоятельную проработку:
— Что такое связывание?
— Какой тип связывания по умолчанию имеют переменные?
— Какой тип связывания по умолчанию имеют константы?
— Какой тип имеет указатель Value1, который ты объявил?
--
Справедливость выше закона. А человечность выше справедливости.
Отредактировано 13.01.2023 22:41 rg45 . Предыдущая версия .
Re[2]: Головоломка с const
От: Shmj Ниоткуда  
Дата: 13.01.23 22:41
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Ну у тебя твой ашник в два (или более) разных сишника включается. В каждом из них создается глобальный символ Value1. А когда линкер пытается свести все это вместе, то он видит, что один и тот же символ объявлен дважды в разных местах, и ругается.


А как же правильно сделать? Что если эти константы нужны в 2-х разных cpp-файлах?
Re[3]: Головоломка с const
От: rg45 СССР  
Дата: 13.01.23 22:43
Оценка: 3 (1)
Здравствуйте, Shmj, Вы писали:

S>А как же правильно сделать? Что если эти константы нужны в 2-х разных cpp-файлах?


Какие ЭТИ КОНСТАНТЫ? Никаких констант ты не объявлял!

Ты объявил НЕКОНСТАНТНЫЙ указатель на константные данные. Другими словами, ты объявил переменную. Понимаешь?
--
Справедливость выше закона. А человечность выше справедливости.
Отредактировано 13.01.2023 22:45 rg45 . Предыдущая версия . Еще …
Отредактировано 13.01.2023 22:44 rg45 . Предыдущая версия .
Re: Головоломка с const
От: пффф  
Дата: 13.01.23 22:44
Оценка: +4 -2
Здравствуйте, Shmj, Вы писали:

S>Такой вопрос-загадка.


Нет никакой загадки


S>...


S>Пол часа жду — та же фигя


S>Потом добавил:


S>
S>static const char* Value1 = "sdfsdfasf";
S>


S>- и о чудо — оно собралось.


Нет никакого чуда


S>Что это могло быть? Какие гипотезы?


Гипотез нет. Есть факты. Факт №1: ты — дурак, не желающий изучать используемые инструменты, и флудящий по этому поводу на форумах
Re[3]: Головоломка с const
От: Pzz Россия https://github.com/alexpevzner
Дата: 13.01.23 22:46
Оценка: 6 (1) +4
Здравствуйте, Shmj, Вы писали:

S>А как же правильно сделать? Что если эти константы нужны в 2-х разных cpp-файлах?


Объяви в ашнике декларацию внешней переменной:
extern const char *Foo;

А фактически переменную заведи в каком-то одном сишнике. Возможно даже, специально для этой цели и предусмотренном:
const char *Foo = "Hello, world!\n";


Узнай для себя новое слово extern.

P.S. А чем тебе новомодный constexpr-то не угодил? Или в макинтош его еще не завезли?
Re[2]: Головоломка с const
От: пффф  
Дата: 13.01.23 22:47
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Слово static делает символ локальным, проблема разрешается, но строка заведется отдельная в каждом сишнике (а в исполняемом файле будет присутствовать много копий одной строки). Почему вендовый линкер не ругается? Ну видимо, сознательно ведет себя неправильно, чтобы таких бедолаг, как ты, не расстраивать.


Чобы ему ругаться?

static по идее вообще из объектника торчать не должен никак
Re[2]: Головоломка с const
От: пффф  
Дата: 13.01.23 22:49
Оценка: :)
Здравствуйте, rg45, Вы писали:

R>Я тебе давно сказал
Автор: rg45
Дата: 05.01.23
— читай про связывание. Вопросы тебе на самостоятельную проработку:


Это — бесполезно. Доктор сказал: "в морг". Значит — в морг
Re[3]: Головоломка с const
От: Pzz Россия https://github.com/alexpevzner
Дата: 13.01.23 22:52
Оценка:
Здравствуйте, пффф, Вы писали:

Pzz>>Слово static делает символ локальным, проблема разрешается, но строка заведется отдельная в каждом сишнике (а в исполняемом файле будет присутствовать много копий одной строки). Почему вендовый линкер не ругается? Ну видимо, сознательно ведет себя неправильно, чтобы таких бедолаг, как ты, не расстраивать.


П>Чобы ему ругаться?


Да нам говорят, что вендовый линкер и без статика не ругается на дублирующийся символ. Я не проверял, мне эта венда 100 лет как без разницы со всеми ее прибамбасами.
Re[4]: Головоломка с const
От: пффф  
Дата: 13.01.23 22:59
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>>>Слово static делает символ локальным, проблема разрешается, но строка заведется отдельная в каждом сишнике (а в исполняемом файле будет присутствовать много копий одной строки). Почему вендовый линкер не ругается? Ну видимо, сознательно ведет себя неправильно, чтобы таких бедолаг, как ты, не расстраивать.


П>>Чобы ему ругаться?


Pzz>Да нам говорят, что вендовый линкер и без статика не ругается на дублирующийся символ. Я не проверял, мне эта венда 100 лет как без разницы со всеми ее прибамбасами.


Без static — ругается. Но может и просто варнинг выдать, если одно и то же. Со static — нет. Ты тоже про связывание только краем уха слышал?
Re[5]: Головоломка с const
От: Pzz Россия https://github.com/alexpevzner
Дата: 13.01.23 23:09
Оценка:
Здравствуйте, пффф, Вы писали:

Pzz>>Да нам говорят, что вендовый линкер и без статика не ругается на дублирующийся символ. Я не проверял, мне эта венда 100 лет как без разницы со всеми ее прибамбасами.


П>Без static — ругается. Но может и просто варнинг выдать, если одно и то же. Со static — нет. Ты тоже про связывание только краем уха слышал?


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

Я даже знаю слово COMDAT. Но краем уха, да.
Re: Головоломка с const
От: rg45 СССР  
Дата: 13.01.23 23:57
Оценка: 6 (1) +1 :)
Здравствуйте, Shmj, Вы писали:

S>Потом добавил:

S>
S>static const char* Value1 = "sdfsdfasf";
S>

S>- и о чудо — оно собралось.
S>Что это могло быть? Какие гипотезы?

Короче, напиши вот так и будет тебе счастье:

const char* const Value1 = "sdfsdfasf";


Обрати внимание на два модификатора const. Таким образом ты объявляешь константный указатель, на константые данные. То есть, это константа. А константы по умолчанию имеют внутреннее связывание. То есть 'static' вместо тебя незримо подставит сам компилятор.

P.S. Не благодари.
--
Справедливость выше закона. А человечность выше справедливости.
Re: Головоломка с const
От: LaptevVV Россия  
Дата: 14.01.23 05:59
Оценка: +1
S>Такой вопрос-загадка.
Нифига это не загадка
S>Понадобилось собрать QT5 -проект на MacOS. Под Windows собрался успешно.
У меня сразу возникают вопросы:
1. Компиляторы были одинаковые в винде и макоси?
2. Версии стандарта в компиляторе установлены одинаковые?
3. Qt были одной и той же версии ?

И напоследок: первая строка кода и последняя (которая собралась) — это две БОЛЬШИЕ разницы, как говорили в Одессе...
Pzz объяснил уже.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[6]: Головоломка с const
От: LaptevVV Россия  
Дата: 14.01.23 06:00
Оценка:
Pzz>Я даже знаю слово COMDAT. Но краем уха, да.
Я его тоже только в настройках Студии видел...
И что оно означает — понятия не имею...
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[7]: Головоломка с const
От: Pzz Россия https://github.com/alexpevzner
Дата: 14.01.23 09:05
Оценка: 1 (1)
Здравствуйте, LaptevVV, Вы писали:

Pzz>>Я даже знаю слово COMDAT. Но краем уха, да.

LVV>Я его тоже только в настройках Студии видел...
LVV>И что оно означает — понятия не имею...

У тебя когда C++, волей-неволей получаются дублирующиеся символы. Ну, например, inline методы в хидере, которые компилятор не осилил проинлайнить, и скомпилировал, как обычную функцию (имеет право, inline — это вежливая просьба, а не приказ).

И с ними надо что-то делать, на уровне линкера. Это — часть этого механизма.
Re[8]: Головоломка с const
От: LaptevVV Россия  
Дата: 14.01.23 09:56
Оценка:
Pzz>>>Я даже знаю слово COMDAT. Но краем уха, да.
LVV>>Я его тоже только в настройках Студии видел...
LVV>>И что оно означает — понятия не имею...
Pzz>У тебя когда C++, волей-неволей получаются дублирующиеся символы. Ну, например, inline методы в хидере, которые компилятор не осилил проинлайнить, и скомпилировал, как обычную функцию (имеет право, inline — это вежливая просьба, а не приказ).
Pzz>И с ними надо что-то делать, на уровне линкера. Это — часть этого механизма.
Спасибо.
Саму схему линкования я студням рассказывал, но до такой конкретики не опускался.
На эту тему есть неплохая книжки (и по-моему единственная) Линкеры и загрузчики (не переведена у нас — а зря).
Много лет назад мне попадалась.
Мож сейчас еще что появилось — давно не интересовался.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re: Головоломка с const
От: vsb Казахстан  
Дата: 14.01.23 10:03
Оценка: -2 :)
Да поставь define и всё, как деды писали, зачем тебе нужны эти новомодные константы, одни проблемы от них.
Re[2]: Головоломка с const
От: rg45 СССР  
Дата: 14.01.23 10:54
Оценка: +1
Здравствуйте, vsb, Вы писали:

vsb>Да поставь define и всё, как деды писали, зачем тебе нужны эти новомодные константы, одни проблемы от них.


Ну вот, а говорил
Автор: vsb
Дата: 13.01.23
, что перфекционист. Это несколько неожиданный совет от перфекциониста.
--
Справедливость выше закона. А человечность выше справедливости.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.