Головоломка с 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
От: пффф  
Дата: 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: Головоломка с 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
От: 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: Головоломка с const
От: vsb Казахстан  
Дата: 14.01.23 10:03
Оценка: -2 :)
Да поставь define и всё, как деды писали, зачем тебе нужны эти новомодные константы, одни проблемы от них.
Re: Головоломка с const
От: Iso12  
Дата: 14.01.23 11:19
Оценка: 8 (1)
Здравствуйте, Shmj, Вы писали:

Есть неплохой доклад на эту тему на CPPCON 2021 :
Back to Basics: const and constexpr — Rainer Grimm
Доклад
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[7]: Головоломка с const
От: Pzz Россия https://github.com/alexpevzner
Дата: 14.01.23 09:05
Оценка: 1 (1)
Здравствуйте, LaptevVV, Вы писали:

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

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

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

И с ними надо что-то делать, на уровне линкера. Это — часть этого механизма.
Re[2]: Головоломка с const
От: пффф  
Дата: 13.01.23 22:49
Оценка: :)
Здравствуйте, rg45, Вы писали:

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


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

И напоследок: первая строка кода и последняя (которая собралась) — это две БОЛЬШИЕ разницы, как говорили в Одессе...
Pzz объяснил уже.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[2]: Головоломка с const
От: rg45 СССР  
Дата: 14.01.23 10:54
Оценка: +1
Здравствуйте, vsb, Вы писали:

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


Ну вот, а говорил
Автор: vsb
Дата: 13.01.23
, что перфекционист. Это несколько неожиданный совет от перфекциониста.
--
Не можешь достичь желаемого — пожелай достигнутого.
Re[3]: Головоломка с const
От: vsb Казахстан  
Дата: 14.01.23 10:58
Оценка: :)
Здравствуйте, rg45, Вы писали:

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


R>Ну вот, а говорил
Автор: vsb
Дата: 13.01.23
, что перфекционист. Это несколько неожиданный совет от перфекциониста.


Ну правильный ответ ты уже дал, а написать что-то мне в субботу хочется )

Я думаю, что если топикстартеру не хочется забивать себе голову всеми этими связываниями и нелогичными синтаксисами, то альтернатива в виде define-а принесёт меньше неожиданностей.
Отредактировано 14.01.2023 10:59 vsb . Предыдущая версия .
Re[5]: Головоломка с const
От: vsb Казахстан  
Дата: 15.01.23 10:24
Оценка: +1
Здравствуйте, AleksandrN, Вы писали:

AN>Однажды он напишет что-то вроде

AN>
AN>#define A 2
AN>#define B 3
AN>#define C A + B
AN>

AN>и удивится, когда подставит С в выражение с операциями, у которых выше приоритет.

Скобки в дефайнах учат ставить сразу после того, как учат этим самым дефайнам.
Отредактировано 15.01.2023 10:24 vsb . Предыдущая версия .
Re[2]: Головоломка с const
От: Shmj Ниоткуда  
Дата: 13.01.23 22:41
Оценка:
Здравствуйте, Pzz, Вы писали:

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


А как же правильно сделать? Что если эти константы нужны в 2-х разных cpp-файлах?
Re[2]: Головоломка с const
От: пффф  
Дата: 13.01.23 22:47
Оценка:
Здравствуйте, Pzz, Вы писали:

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


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

static по идее вообще из объектника торчать не должен никак
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[6]: Головоломка с const
От: LaptevVV Россия  
Дата: 14.01.23 06:00
Оценка:
Pzz>Я даже знаю слово COMDAT. Но краем уха, да.
Я его тоже только в настройках Студии видел...
И что оно означает — понятия не имею...
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[8]: Головоломка с const
От: LaptevVV Россия  
Дата: 14.01.23 09:56
Оценка:
Pzz>>>Я даже знаю слово COMDAT. Но краем уха, да.
LVV>>Я его тоже только в настройках Студии видел...
LVV>>И что оно означает — понятия не имею...
Pzz>У тебя когда C++, волей-неволей получаются дублирующиеся символы. Ну, например, inline методы в хидере, которые компилятор не осилил проинлайнить, и скомпилировал, как обычную функцию (имеет право, inline — это вежливая просьба, а не приказ).
Pzz>И с ними надо что-то делать, на уровне линкера. Это — часть этого механизма.
Спасибо.
Саму схему линкования я студням рассказывал, но до такой конкретики не опускался.
На эту тему есть неплохая книжки (и по-моему единственная) Линкеры и загрузчики (не переведена у нас — а зря).
Много лет назад мне попадалась.
Мож сейчас еще что появилось — давно не интересовался.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[9]: Головоломка с const
От: Pzz Россия https://github.com/alexpevzner
Дата: 14.01.23 11:21
Оценка:
Здравствуйте, LaptevVV, Вы писали:

Pzz>>И с ними надо что-то делать, на уровне линкера. Это — часть этого механизма.

LVV>Спасибо.
LVV>Саму схему линкования я студням рассказывал, но до такой конкретики не опускался.

Я это очень поверхностно знаю. Мне Юра Харон, известный больше в ФИДО, чем тут, по телефону рассказывал

Но меня вымораживает, если честно, что преподаватель C++ не знает таких вещей. Я C++ не знаю, сознательно прошел мимо него, а и то в курсе.

LVV>На эту тему есть неплохая книжки (и по-моему единственная) Линкеры и загрузчики (не переведена у нас — а зря).


Это — очень старая книжка. С появлением C++ появились новые проблемы, типа этой, которых раньше не было.

Вроде был советский перевод, но я на 100% не уверен.
Re[10]: Головоломка с const
От: LaptevVV Россия  
Дата: 14.01.23 11:30
Оценка:
Pzz>Но меня вымораживает, если честно, что преподаватель C++ не знает таких вещей. Я C++ не знаю, сознательно прошел мимо него, а и то в курсе.
Это одна конкретная реализация конкретной фирмы.
Тем более, я микрософт не люблю...
Если для работы понадобится — я разберусь.
Я и внутрь gcc не лазил -потребности же не было серьезной.
LVV>>На эту тему есть неплохая книжки (и по-моему единственная) Линкеры и загрузчики (не переведена у нас — а зря).
Pzz>Это — очень старая книжка. С появлением C++ появились новые проблемы, типа этой, которых раньше не было.
Да, я ее в конце 90-х еще с инета качал.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[4]: Головоломка с const
От: AleksandrN Россия  
Дата: 14.01.23 21:07
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Я думаю, что если топикстартеру не хочется забивать себе голову всеми этими связываниями и нелогичными синтаксисами, то альтернатива в виде define-а принесёт меньше неожиданностей.


#define — не объявление константы, а подстановка символов вместо макроса.

Однажды он напишет что-то вроде
#define A 2
#define B 3
#define C A + B

и удивится, когда подставит С в выражение с операциями, у которых выше приоритет.
Re[5]: Головоломка с const
От: пффф  
Дата: 14.01.23 23:45
Оценка:
Здравствуйте, AleksandrN, Вы писали:

vsb>>Я думаю, что если топикстартеру не хочется забивать себе голову всеми этими связываниями и нелогичными синтаксисами, то альтернатива в виде define-а принесёт меньше неожиданностей.


AN>#define — не объявление константы, а подстановка символов вместо макроса.


AN>Однажды он напишет что-то вроде

AN>
AN>#define A 2
AN>#define B 3
AN>#define C A + B
AN>

AN>и удивится, когда подставит С в выражение с операциями, у которых выше приоритет.


Шмыги, не желающие ничего изучать — должны страдать.

Но, как я помню недавние дискуссии — ему это не грозит. Он C++ уже пару недель изучает, и не нашел там ничего сложного
Re[4]: Головоломка с const
От: Doom100500 Израиль  
Дата: 15.01.23 10:20
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Я думаю, что если топикстартеру не хочется забивать себе голову всеми этими связываниями и нелогичными синтаксисами, то альтернатива в виде define-а принесёт меньше неожиданностей.



Не, тут только в дальнобойщики идти. Програмирование на этом — всё .
Спасибо за внимание
Отредактировано 15.01.2023 10:21 Doom100500 . Предыдущая версия .
Re[6]: Головоломка с const
От: Doom100500 Израиль  
Дата: 15.01.23 11:07
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Здравствуйте, AleksandrN, Вы писали:


AN>>Однажды он напишет что-то вроде

AN>>
AN>>#define A 2
AN>>#define B 3
AN>>#define C A + B
AN>>

AN>>и удивится, когда подставит С в выражение с операциями, у которых выше приоритет.

vsb>Скобки в дефайнах учат ставить сразу после того, как учат этим самым дефайнам.


Ключевое слово — учат.
Спасибо за внимание
Re[6]: Головоломка с const
От: rg45 СССР  
Дата: 15.01.23 11:20
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Скобки в дефайнах учат ставить сразу после того, как учат этим самым дефайнам.


Только это не отменяет того факта, что макросы — это просто манипуляции с текстом, которые выполняются до того, как текст программы передается компилятору. Поэтому называть макроопределение объявлением константы — это несколько неправильно — никаких констант не создается при этом.
--
Не можешь достичь желаемого — пожелай достигнутого.
Отредактировано 15.01.2023 13:50 rg45 . Предыдущая версия . Еще …
Отредактировано 15.01.2023 11:21 rg45 . Предыдущая версия .
Re[6]: Головоломка с const
От: _NN_ www.nemerleweb.com
Дата: 15.01.23 14:08
Оценка:
Здравствуйте, vsb, Вы писали:

vsb>Здравствуйте, AleksandrN, Вы писали:


AN>>Однажды он напишет что-то вроде

AN>>
AN>>#define A 2
AN>>#define B 3
AN>>#define C A + B
AN>>

AN>>и удивится, когда подставит С в выражение с операциями, у которых выше приоритет.

vsb>Скобки в дефайнах учат ставить сразу после того, как учат этим самым дефайнам.


И учат ставить всегда пробелы

#define A(b) 0x123e+(b)
int x = A(1); // error: invalid suffix "+" on integer constant

#define B(b) 0x123e + (b)
int y = B(1); // Работает как ожидается
http://rsdn.nemerleweb.com
http://nemerleweb.com
Отредактировано 15.01.2023 14:09 _NN_ . Предыдущая версия .
Re[4]: Головоломка с const
От: B0FEE664  
Дата: 16.01.23 13:39
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>P.S. А чем тебе новомодный constexpr-то не угодил? Или в макинтош его еще не завезли?


Скорее всего у него отсутствует строчка CONFIG += c++17 в его .pro проекте.
И каждый день — без права на ошибку...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.